Attempt to make dll wrapper, compiles no errors, but no success.

Previous topic - Next topic

aonyn

Hi All,

Good news, I think I have a solution, my initial test works as expected.
I tried unicode, and that still did not work correctly.
The key was, UTF8 as the expected string format.
I am using a helper dll which I am writing in purebasic with pseudotypes.

Here is the code in purebasic.
Code (glbasic) Select

Prototype pbp_xAppTitle(title.p-utf8)

ProcedureDLL xAppTitle(title.s)
If OpenLibrary(0, "xors3d.dll")
pb_xAppTitle.pbp_xAppTitle = GetFunction(0, "_xAppTitle@4")
pb_xAppTitle(title)
CloseLibrary(0)
EndIf
EndProcedure


Then I declare the helper dll this way in GLBasic.
Code (glbasic) Select

DECLARE_ALIAS(glb_xAppTitle, "xors3d_TextConvert.dll", "xAppTitle", (const char*), void);


And finally I wrap it in a GLBasic function.
Code (glbasic) Select

FUNCTION xAppTitle: title$
INLINE
if(glb_xAppTitle)
glb_xAppTitle(title_Str.c_str());
ENDINLINE
ENDFUNCTION


And EUREKA, it works!!!
Perhaps there is a more efficient way to do it, but for now, I am just happy to have solved the problem, and can continue wrapping xors3d.  =D

Thanks everyone for all your input.
Without the hints, I would probably still be stuck on step 1.

regards,
Dave
For by grace are ye saved through faith, and that not of yourselves: it is the gift of God: Not of works, lest any man should boast. -Ephesians 2:8-9

aonyn

Well, sending arguments to UTF8 is solved  :)
however, receiving the return back to ascii, not so much  :doubt:

Well, I will figure it out, I at least know what the problem is.  :good:
I will post back as I make progress.

Regards,
Dave
For by grace are ye saved through faith, and that not of yourselves: it is the gift of God: Not of works, lest any man should boast. -Ephesians 2:8-9

aonyn

Hi Ocean,

Thanks, the tip was very helpful.

Some built in method of communicating with different string encodings would be very useful indeed.

Purebasic handles it with pseudotypes, but from what I can tell, pseudotypes only work with parameters, not returns.
I think I will have to write a function to manually decode the return.

It appears that the best way to do this will involve allocating memory, and a lot of peak/poke.
This is all new territory for me, but I will certainly learn a lot doing it.

regards,
Dave
For by grace are ye saved through faith, and that not of yourselves: it is the gift of God: Not of works, lest any man should boast. -Ephesians 2:8-9

aonyn

Hi All,

EUREKA! It works, finally!   :booze:
I am passing strings both to and from the xors3d dll, with a bit of help from PureBasic.

Here is how I am passing strings to:

PureBasic DLL
Code (glbasic) Select

Prototype pbp_xChangeDir(path.p-utf8)

ProcedureDLL xChangeDir(path.s)
If OpenLibrary(0, "xors3d.dll")
pb_xChangeDir.pbp_xChangeDir = GetFunction(0, "_xChangeDir@4")
CloseLibrary(0)
EndIf
EndProcedure


GLBasic Wrapper
Code (glbasic) Select

INLINE
extern "C"
{
DECLARE_ALIAS(glb_xChangeDir, "xors3d_TextConvert.dll", "xChangeDir", (const char*), void);
}
ENDINLINE

FUNCTION xChangeDir: path$
INLINE
if(glb_xChangeDir)
glb_xChangeDir(path_Str.c_str());
ENDINLINE
ENDFUNCTION


And here is how I am receiving strings from:

PureBasic DLL
Code (glbasic) Select

Prototype.i pbp_xCurrentDir()

ProcedureDLL.s xCurrentDir()
If OpenLibrary(0, "xors3d.dll")
pb_xCurrentDir.pbp_xCurrentDir = GetFunction(0, "_xCurrentDir@0")
outputString$ = PeekS(pb_xCurrentDir())
CloseLibrary(0)
ProcedureReturn outputString$
EndIf
EndProcedure


GLBasic Wrapper
Code (glbasic) Select

INLINE
extern "C"
{
DECLARE_ALIAS(glb_xChangeDir, "xors3d_TextConvert.dll", "xChangeDir", (const char*), void);
}
ENDINLINE

FUNCTION xCurrentDir$:
LOCAL currentDir$
INLINE
if(glb_xCurrentDir)
currentDir_Str = glb_xCurrentDir();
ENDINLINE
RETURN currentDir$
ENDFUNCTION


Now the part which baffles me a bit is, the dll function is supposed to return a const char* according to the documentation.
However, to get the return, I had to receive the return as an integer, then used the function as the argument for the PeekS command.
This argument refers to a memory address, so it appears the function returns a memory address to the string, and I am grabbing the string from memory, and saving it to a variable which finally I am returning to GLBasic.

Is this expected behavior for a const char* return, or is the function acting differently than it is documented?

No matter though, because what I have done is now working as expected, and I am moving forward with the wrapper. I would still like to know why this works as it does though, to satisfy my own curiosity, so feedback is appreciated.

Thanks everyone for your help, and of course I will provide this wrapper to the community (including the PureBasic source code) when it is ready, although I can't promise I will be done quickly, as I am doing this for amusement, and have real world responsibilities which must come first. Also, I am still on the coding learning curve, so I can't say whether I will hit more stumbling blocks along the way, but I am sure I will have fun solving problems, and learning new skills.

regards,
Dave
For by grace are ye saved through faith, and that not of yourselves: it is the gift of God: Not of works, lest any man should boast. -Ephesians 2:8-9

MrTAToad

Dont forget that a const char pointer is a pointer to a memory address, so that would be more or less correct.

aonyn

Thanks MrTAToad,

Explained that way, it does make sense.

regards,
Dave
For by grace are ye saved through faith, and that not of yourselves: it is the gift of God: Not of works, lest any man should boast. -Ephesians 2:8-9