String Compatibility Problem Between XP and Vista

Just starting out? Need help? Post your questions and find answers here.
User avatar
Randy
User
User
Posts: 29
Joined: Sat Sep 30, 2006 11:36 pm
Location: Atlanta, Georgia

String Compatibility Problem Between XP and Vista

Post by Randy »

Hi all,

I wrote a simple DLL for Dark Basic Pro and it returns a string without a problem in XP. In Vista, unless I put the compatibility mode in Win 98/Me, it crashes. Does anyone have any ideas as to why it works flawlessly in one and not the other? (Code below)

Code: Select all

; needed Structures 
Structure GlobChecklistStruct
  dwStringSize.l : string.s : valuea.l : valueb.l : valuec.l : valued.l
EndStructure
Structure GlobStruct
  ; Function Ptrs (For remote DLLs)
  CreateDeleteString.l : ProcessMessageFunction.l : PrintStringFunction.l : UpdateFilenameFromVirtualTable.l : Decrypt.l : Encrypt.l
  ChangeMouseFunction.l : SpareFunction1.l : SpareFunction2.l : SpareFunction3.l : g_pVariableSpace.l : g_pErrorHandlerRef.l
  ; DLL Handles And Active Flags
  g_GFX.l : g_Text.l : g_Basic2D.l : g_Sprites.l : g_Image.l : g_Input.l : g_System.l : g_File.l : g_FTP.l : g_Memblocks.l
  g_Bitmap.l : g_Animation.l : g_Multiplayer.l : g_Basic3D.l : g_Camera3D.l : g_Matrix3D.l : g_Light3D.l : g_World3D.l
  g_Particles.l : g_PrimObject.l : g_Vectors.l : g_XObject.l : g_3DSObject.l : g_MDLObject.l : g_MD2Object.l : g_MD3Object.l
  g_Sound.l : g_Music.l : g_LODTerrain.l : g_Q2BSP.l : g_OwnBSP.l : g_BSPCompiler.l : g_CSG.l
  g_Spare01.l : g_Spare02.l : g_Spare03.l : g_Spare04.l : g_Spare05.l : g_Spare06.l : g_Spare07.l : g_Spare08.l : g_Spare09.l
  g_Spare10.l : g_Spare11.l :  g_Spare12.l : g_Spare13.l : g_Spare14.l : g_Spare15.l : g_Spare16.l : g_Spare17.l : g_Spare18.l
  g_Spare19.l : g_Spare20.l 
  g_GFXmade.b : g_Textmade.b : g_Basic2Dmade.b : g_Spritesmade.b : g_Imagemade.b : g_Inputmade.b : g_Systemmade.b : g_Filemade.b
  g_FTPmade.b : g_Memblocksmade.b : g_Bitmapmade.b : g_Animationmade.b : g_Multiplayermade.b : g_Basic3Dmade.b : g_Camera3Dmade.b
  g_Matrix3Dmade.b : g_Light3Dmade.b : g_World3Dmade.b : g_Particlesmade.b : g_PrimObjectmade.b : g_Vectorsmade.b : g_XObjectmade.b
  g_3DSObjectmade.b : g_MDLObjectmade.b : g_MD2Objectmade.b : g_MD3Objectmade.b : g_Soundmade.b : g_Musicmade.b : g_LODTerrainmade.b
  g_Q2BSPmade.b : g_OwnBSPmade.b : g_BSPCompilermade.b : g_CSGmade.b
  g_Spare01made.b : g_Spare02made.b : g_Spare03made.b : g_Spare04made.b : g_Spare05made.b : g_Spare06made.b : g_Spare07made.b
  g_Spare08made.b : g_Spare09made.b : g_Spare10made.b : g_Spare11made.b : g_Spare12made.b : g_Spare13made.b : g_Spare14made.b
  g_Spare15made.b : g_Spare16made.b : g_Spare17made.b : g_Spare18made.b : g_Spare19made.b : g_Spare20made.b
  ; Executable Media Handling Data
  pEXEUnpackDirectory.b[260] ; [MAX_PATH]
  dwEncryptionUniqueKey.l : ppEXEAbsFilename.l : dwEMHDSpare2.l : dwEMHDSpare3.l : dwEMHDSpare4.l : dwEMHDSpare5.l
  ; Windows General Data
  HWND.l : HINSTANCE.l : pWindowsTextEntry.s : bInvalidFlag.b : dwWindowWidth.l : dwWindowHeight.l : hAppIcon.l
  dwAppDisplayModeUsing.l : dwWindowX.l : dwWindowY.l : dwWGDSpare1.l : dwWGDSpare2.l : dwWGDSpare3.l : dwWGDSpare4.l : dwWGDSpare5.l
   ; Windows Mouse Data
  bWindowsMouseVisible.b : iWindowsMouseX.l : iWindowsMouseY.l : iWindowsMouseClick.l : dwWMDSpare2.l : dwWMDSpare3.l : dwWMDSpare4.l
  dwWMDSpare5.l
  ; Main Screen Data (backbuffer)
  iScreenWidth.l : iScreenHeight.l : iScreenDepth.l : iNoDrawLeft.l : iNoDrawTop.l : iNoDrawRight.l : iNoDrawBottom.l
  dwSafeRectMax.l : pSafeRects.l : dwMSDSpare3.l : dwMSDSpare4.l : dwMSDSpare5.l
  ; Bitmap And Surface Data (For drawing offscreen)
  iCurrentBitmapNumber.l : pCurrentBitmapTexture.l : pCurrentBitmapSurface.l : pHoldBackBufferPtr.l :  pHoldDepthBufferPtr.l
  dwBSDSpare1.l : dwBSDSpare2.l : dwBSDSpare3.l : dwBSDSpare4.l : dwBSDSpare5.l 
  ; drawing Data
  iCursorX.l : iCursorY.l : dwForeColor.l : dwBackColor.l : dwRenderCameraID.l : fReflectionPlaneX.f : fReflectionPlaneY.f
  fReflectionPlaneZ.f : dwDDSpare1.l : dwDDSpare2.l : dwDDSpare3.l : dwDDSpare4.l : dwDDSpare5.l
  ; Checklist Data
  checklistexists.b : checklisthasvalues.b : checklisthasstrings.b : checklistqty.l : dwChecklistArraySize.l
  Checklist.GlobChecklistStruct
  ; Dependent 3D Data Exchange
  iFogState.l : dwRedrawPhase.l : dwRedrawCount.l : dwStencilMode.l : dwStencilShadowCount.l : dwStencilReflectionCount.l
  dwNumberOfPolygonsDrawn.l : dwNumberOfPrimCalls.l : dwStencilSpare3.l : dwStencilSpare4.l : dwStencilSpare5.l
  ; System States And Global Controls
  bEscapeKeyEnabled.b : bSystemKeyEnabled.b : bSpareBool1.b : bSpareBool2.b : bSpareBool3.b : bSpareBool4.b : bSpareBool5.b
  bSpareBool6.b : bSpareBool7.b : bSpare8.b : bSpare9.b : pExitPromptString.s : pExitPromptString2.s : iSoftwareVP.l  
  ; Dynamic Memory Area For future expansion
  dwDynMemSize.l : dwDynMemPtr.s
EndStructure
Global *GlobPtr.GlobStruct
Structure char ; character structure
  a.b
EndStructure

Global gret$

ProcedureCDLL Constructor()
EndProcedure

ProcedureCDLL Destructor()
EndProcedure

Procedure.l InitialiseCorePtr()
  If OpenLibrary(3, "DarkBasic ProfessionalCore.dll")
    coreptr_handle.l = GetFunction(3, "?GetGlobPtr@@YAKXZ")
    *GlobPtr = CallCFunctionFast(coreptr_handle)
    CloseLibrary(3)
  EndIf
  ProcedureReturn *GlobPtr
EndProcedure

Macro InitCore
If *GlobPtr = 0 : InitialiseCorePtr() : EndIf
EndMacro

ProcedureCDLL.l Test(gret.l, filenum.l, field.l)
  InitCore
;stripped out the rest of the code to test just the string handling and this seems to be the issue.  
  gret$ = "Test"
  ProcedureReturn @gret$
EndProcedure
Thanks,

Randy
Maybe it's just a bunch of stuff that happens -- Homer Simpson
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Just a question.

In the InitialiseCorePtr() function you retrieve a structure pointer from a dll which, if I am correct, contains function pointers amongst other things. You then close the library. Well, if these function pointers are pointing to functions inside what is a now closed library.... CRASH.

Just wondering? I've probably misread the code! :)
I may look like a mule, but I'm not a complete ass.
User avatar
Randy
User
User
Posts: 29
Joined: Sat Sep 30, 2006 11:36 pm
Location: Atlanta, Georgia

Post by Randy »

I'm not sure I understand fully what it does. This is the header that is given in their tutorial on how to do this.

It works in XP flawlessly. In fact, before I stripped it down to what you see here, it was retrieving data from a file, massaging it, and giving back an answer in the form of a string with over ten thousand records. It's only when I use this in Vista that it causes the problem. Someone else tried it with Windows 7 and got it as well.

Lastly, I can return integers, floats, and doubles with Vista with no problem. It just seems to be strings which is what is baffling to me.

Randy
Maybe it's just a bunch of stuff that happens -- Homer Simpson
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Well, if those pointers point to functions inside the dll then you really shouldn't be closing the library.
I may look like a mule, but I'm not a complete ass.
User avatar
Randy
User
User
Posts: 29
Joined: Sat Sep 30, 2006 11:36 pm
Location: Atlanta, Georgia

Post by Randy »

I commented out the closelibrary() function and it didn't make a difference for XP which is good. It did affect Vista in that it partially worked. Now it only crashes the majority of the time instead of all the time. :lol:
Maybe it's just a bunch of stuff that happens -- Homer Simpson
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

I would search the code looking for similar problems because I have never had problems with Vista and dll's etc.

You have to always take care when returning strings from dll's in that you don't want either the dll or the client attempting to free string memory which has been allocated in the other. This is a common problem and invariably leads to crashes. The best way of returning strings is via a buffer or a pointer to a global string etc. so have a good look at the code of both the dll and the client. :wink:
I may look like a mule, but I'm not a complete ass.
User avatar
Randy
User
User
Posts: 29
Joined: Sat Sep 30, 2006 11:36 pm
Location: Atlanta, Georgia

I solved it

Post by Randy »

Apparently PB 4.xx has made some improvements. I just found that I no longer need to worry with addresses and pointers. All I had to do was define the procedure as procedure.s and simply return gret$. No @ or * or anything of the sort.

It was one of those moments where I said, "I've tried everything I can think of so let's get desperate!"

I'll have to post how to do this for other PB'ers in case anyone wants to know. It works for XP and Vista and hopefully Version 7.

Randy
Maybe it's just a bunch of stuff that happens -- Homer Simpson
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

That has always been an option with Purebasic as I understand it.

Personally I tend to avoid using global strings that way because they are not necessarily threadsafe (unless the string is constant). I use buffers instead.
I may look like a mule, but I'm not a complete ass.
User avatar
Randy
User
User
Posts: 29
Joined: Sat Sep 30, 2006 11:36 pm
Location: Atlanta, Georgia

A simple example?

Post by Randy »

Hi Srod,

I'm not used to buffers so that might actually be the way to go to be on the safe side. Could you give me a simple example?

Randy
Maybe it's just a bunch of stuff that happens -- Homer Simpson
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

If you have a dll function from which you wish to return a string then instead have it return the length (in characters) of the string. Have it also take a parameter which points to the address of a buffer which the client is responsible for allocating. If this parameter is non-zero then poke the string into the buffer.

What the client will typically do is call the function to get the required length of the string. It then uses something like buffer$ = Space(numCharacters) and then calls the function again with @buffer$ as the aforementioned parameter.

On return, buffer$ will contain the string.

You can get away with calling the function just once if you know the maximum length of the string to be returned etc.
I may look like a mule, but I'm not a complete ass.
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Post by Mistrel »

The DBP global structure stores a 32-bit address to an internal function CreateDeleteString. You can use this to return a string to DBP that it can then free later without risking the string being freed twice.

Code: Select all

g_pGlob->CreateDeleteString((DWORD*)&pOldString, 0)
You'll have to use either CallCFunctionFast or prototypes in PureBasic to use it.

See here:

http://forum.thegamecreators.com/?m=for ... =44568&b=1
http://forum.thegamecreators.com/?m=for ... =32655&b=1
User avatar
Randy
User
User
Posts: 29
Joined: Sat Sep 30, 2006 11:36 pm
Location: Atlanta, Georgia

Post by Randy »

Hi Mistral,

I tried that too. Vista and apparently Windows 7 somehow 'leak'. I can get it to return a string about eight times before it crashes now instead of immediately. However, I'm going to play around with it again and see.

I'll report any findings in a little while.

Thanks Srod and Mistral for your knowledge and help,

Randy
Maybe it's just a bunch of stuff that happens -- Homer Simpson
Duffer123
User
User
Posts: 42
Joined: Fri Nov 30, 2012 11:40 pm

Re: String Compatibility Problem Between XP and Vista

Post by Duffer123 »

Did anyone actually get to the bottom of this - I am trying to create functions returning strings with ProcedureCDLL.l for commands in to DarkBasicPro (latest versions of DBPro and PB owned) and I get crashes (in Windows 7 and Vista) -

Has anyone figured out the secret to it that seems to have illuded everyone in this thread???
Post Reply