Page 1 of 1

Strange problem with dll and structure

Posted: Fri Nov 18, 2011 8:31 pm
by RichAlgeni
I have create a simple test process with a console program and a dll, using a structure:

Code: Select all

; testdll01.pb

EnableExplicit

Structure structureData
    stringOne.s
    stringTwo.s
    stringThree.s
EndStructure

ProcedureDLL AttachProcess(instance)
EndProcedure

ProcedureDLL DetachProcess(instance)
EndProcedure

ProcedureDLL AttachThread(instance)
EndProcedure

ProcedureDLL DetachThread(instance)
EndProcedure

ProcedureDLL concatString(*memLoc.structureData)
    Protected partOne.s   = *memLoc\stringOne
    Protected partTwo.s   = *memLoc\stringTwo
    Protected partThree.s = partOne + partTwo
    *memLoc\stringThree   = partThree
EndProcedure

; IDE Options = PureBasic 4.51 (Windows - x64)
; ExecutableFormat = Shared Dll
; CursorPosition = 1
; Folding = -
; Executable = testdll01.dll
; CurrentDirectory = D:\dev\PureBasic\temp\
; CompileSourceDirectory

Code: Select all

; testing01.pb

EnableExplicit

Structure structureData
    stringOne.s
    stringTwo.s
    stringThree.s
EndStructure

Procedure ProcessThis()
    Protected libraryfile0.s = "testdll01.dll"
    Protected libraryNumber0
    Protected *thisData.structureData

    *thisData.structureData = AllocateMemory(SizeOf(structureData))
    *thisData\stringOne     = "This is string one, "
    *thisData\stringTwo     = "this is string two"

; open the library if needed, then run the dll

    libraryNumber0 = OpenLibrary(#PB_Any, libraryfile0)
    PrintN("OpenLibrary " + libraryfile0 + " = " + Str(libraryNumber0))

    If  libraryNumber0 > 0
        CallFunction(libraryNumber0, "concatString", *thisData)
        PrintN(*thisData\stringThree)
    Else
        PrintN("Unable to run CallFunction concatString")
    EndIf

    ClearStructure(*thisData, structureData)
    FreeMemory(*thisData)
EndProcedure

OpenConsole()
ProcessThis()
Input()
CloseConsole()

End

; IDE Options = PureBasic 4.51 (Windows - x64)
; Folding = -
; ExecutableFormat = Console
; CurrentDirectory = D:\dev\PureBasic\temp\
; CompileSourceDirectory
Here's the problem: The main process dies with an error unless either CallFunction(libraryNumber0, "concatString", *thisData) or ClearStructure(*thisData, structureData) are commented out in testing01.pb.

If I create a new process by removing the call to the dll, and just call the procedure as normal, all is fine:

Code: Select all

; testing02.pb

EnableExplicit

Structure structureData
    stringOne.s
    stringTwo.s
    stringThree.s
EndStructure

Procedure concatString(*memLoc.structureData)
    Protected partOne.s   = *memLoc\stringOne
    Protected partTwo.s   = *memLoc\stringTwo
    Protected partThree.s = partOne + partTwo
    *memLoc\stringThree   = partThree
EndProcedure

Procedure ProcessThis()
    Protected *thisData.structureData

    *thisData.structureData = AllocateMemory(SizeOf(structureData))
    *thisData\stringOne     = "This is string one, "
    *thisData\stringTwo     = "this is string two"

; open the library if needed, then run the dll

    concatString(*thisData)
    PrintN(*thisData\stringThree)

    ClearStructure(*thisData, structureData)
    FreeMemory(*thisData)
EndProcedure

OpenConsole()
ProcessThis()
Input()
CloseConsole()

End

; IDE Options = PureBasic 4.51 (Windows - x64)
; Folding = -
; ExecutableFormat = Console
; CurrentDirectory = D:\dev\PureBasic\temp\
; CompileSourceDirectory
Am I missing something???

Re: Strange problem with dll and structure

Posted: Fri Nov 18, 2011 8:57 pm
by luis
I hope I'm not saying something wrong, but in the case someone will certainly correct me :)

I believe the problem is you allocate the memory in the calling process, and then in the dll you try to attach a string allocated by the dll to that memory area, mixing memory allocated by the calling process and by the dll.

A test:

Code: Select all

; testdll01.pb

EnableExplicit

Structure structureData
    stringOne.s
    stringTwo.s
    stringThree.s
EndStructure

ProcedureDLL AttachProcess(instance)
EndProcedure

ProcedureDLL DetachProcess(instance)
EndProcedure

ProcedureDLL AttachThread(instance)
EndProcedure

ProcedureDLL DetachThread(instance)
EndProcedure

ProcedureDLL concatString(*memLoc.structureData)
    Protected partOne.s   = *memLoc\stringOne
    Protected partTwo.s   = *memLoc\stringTwo
    Protected partThree.s = partOne + partTwo
    PokeS(@*memLoc\stringThree,partThree)
EndProcedure

Code: Select all

EnableExplicit

Structure structureData
    stringOne.s
    stringTwo.s
    stringThree.s
EndStructure

Procedure ProcessThis()
    Protected libraryfile0.s = "testdll01.dll"
    Protected libraryNumber0
    Protected *thisData.structureData

    *thisData.structureData = AllocateMemory(SizeOf(structureData))
    *thisData\stringOne     = "This is string one, "
    *thisData\stringTwo     = "this is string two"
    *thisData\stringThree   = Space(255)

; open the library if needed, then run the dll

    libraryNumber0 = OpenLibrary(#PB_Any, libraryfile0)
    PrintN("OpenLibrary " + libraryfile0 + " = " + Str(libraryNumber0))

    If  libraryNumber0 > 0
        CallFunction(libraryNumber0, "concatString", *thisData)
        PrintN(*thisData\stringThree)
    Else
        PrintN("Unable to run CallFunction concatString")
    EndIf

    ClearStructure(*thisData, structureData)
    FreeMemory(*thisData)
EndProcedure

OpenConsole()
ProcessThis()
Input()
CloseConsole()

End

In this code the memory for the returned string is allocated in the calling process, and the dll simply write into it.
This does not crash.

In your code ClearStructure crash when it's trying to release the third string inside the structure (allocated not by that process).

Re: Strange problem with dll and structure

Posted: Fri Nov 18, 2011 9:08 pm
by RichAlgeni
Luis, you are a gentleman, scholar, and judge of fine wine and women!

Not too mention code!

Thanks so much!

Rich