Pointer Returned from DLL Call

Bare metal programming in PureBasic, for experienced users
MGD
User
User
Posts: 16
Joined: Wed Jul 27, 2022 8:31 pm

Pointer Returned from DLL Call

Post by MGD »

Relatively new to PB and trying to work with calling a DLL. Specifically looking at interfacing to the Julia runtime as described here: https://docs.julialang.org/en/v1/manual ... ding-Julia. While the calls are not crashing, it's also not clear that parameter passing is working. In particular, I'm having a hard time with pointer return types on the Prototype statements. I've also confusingly seen in other forum posts where no return type annotation even seems to be necessary, and things just work, though in my case, if I don't use the @ sign in the subsequent call that uses the returned pointer, it crashes. Everything in 64-bit (I'm aware the PrototypeC isn't necessary in this case -- just covering all bases).
Testing code:

Code: Select all

If OpenConsole()

juliaLib = OpenLibrary(#PB_Any, "C:\msys64\home\XXX\julia\usr\bin\libjulia.dll")

PrototypeC ProtoJL_Init()
PrototypeC ProtoJL_Eval_String(Eval$)
PrototypeC ProtoJL_AtExit_Hook(Status.i)
PrototypeC.d ProtoJL_Unbox_Float64(*jlptr)
PrototypeC.l ProtoJL_Unbox_Int32(*jlptr)
PrototypeC ProtoJL_Box_Float64(num.d)
PrototypeC.s ProtoJL_TypeOf_Str(*jlptr)

jl_init.ProtoJL_Init = GetFunction(juliaLib,"jl_init")
jl_eval_string.ProtoJL_Eval_String = GetFunction(juliaLib,"jl_eval_string")
jl_atexit_hook.ProtoJL_AtExit_Hook = GetFunction(juliaLib,"jl_atexit_hook")
jl_unbox_float64.ProtoJL_Unbox_Float64 = GetFunction(juliaLib,"jl_unbox_float64")
jl_unbox_int32.ProtoJL_Unbox_Int32 = GetFunction(juliaLib,"jl_unbox_int32")
jl_box_float64.ProtoJL_Box_Float64 = GetFunction(juliaLib,"jl_box_float64")
jl_typeof_str.ProtoJL_TypeOf_Str = GetFunction(juliaLib,"jl_typeof_str")

PrintN("init")
jl_init()
PrintN("eval")
jummy = jl_eval_string("Float64(sqrt(2.0))")
PrintN("typeof"+jl_typeof_str(@jummy))
PrintN("unbox")
jrslt = jl_unbox_float64(@jummy)
PrintN(StrD(jrslt))
PrintN("Eval2")
jummy = jl_eval_string("1+2")
PrintN("typeof"+jl_typeof_str(@jummy))
PrintN("unbox2")
jrslt = jl_unbox_int32(@jummy)
PrintN(Str(jrslt))
PrintN("Box float")
f64.d = 3.14
jummy = jl_box_float64(f64)
PrintN("typeof"+jl_typeof_str(@jummy))
PrintN("Unbox float")
jrslt = jl_unbox_float64(@jummy)
PrintN(StrD(jrslt))
PrintN("atexit")
jl_atexit_hook(0)
EndIf
Output:

Code: Select all

init
eval
typeof
unbox
0
Eval2
typeof
unbox2
499159808
Box float
typeof
Unbox float
0
atexit
Note that if I take the type annotations off on the prototypes entirely, it doesn't crash and I get:

Code: Select all

init
eval
typeof0
unbox
140696253799672
Eval2
typeof0
unbox2
2622853888
Box float
typeof0
Unbox float
140696253799672
atexit
Any immediate idea what's going on here? Thanks!
User avatar
Bisonte
Addict
Addict
Posts: 1305
Joined: Tue Oct 09, 2007 2:15 am

Re: Pointer Returned from DLL Call

Post by Bisonte »

If you declare a prototype or variable without anything as Returntype, PB uses automaticly Integer as Returntype ( .i )

Code: Select all

*jummy = jl_box_float64(f64)
PrintN("typeof"+jl_typeof_str(*jummy))
so it should work without @ ...
PureBasic 6.21 (Windows x64) | Windows 11 Pro | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
English is not my native language... (I often use DeepL.)
MGD
User
User
Posts: 16
Joined: Wed Jul 27, 2022 8:31 pm

Re: Pointer Returned from DLL Call

Post by MGD »

Ok, if I convert to using the * with the default declaration (i):

Code: Select all

PrototypeC.s ProtoJL_TypeOf_Str(*jlptr)
Then the relevant output line is:

Code: Select all

typeof2336468239976
If I specify a string type,

Code: Select all

PrototypeC.s ProtoJL_TypeOf_Str(*jlptr)
then I get:

Code: Select all

typeof
MGD
User
User
Posts: 16
Joined: Wed Jul 27, 2022 8:31 pm

Re: Pointer Returned from DLL Call

Post by MGD »

In the second case, which I think is correct, do I have to do something to convert back from UTF-8?
MGD
User
User
Posts: 16
Joined: Wed Jul 27, 2022 8:31 pm

Re: Pointer Returned from DLL Call

Post by MGD »

Finally got it figured out. For posterity:

Code: Select all

PrototypeC ProtoJL_Init()
PrototypeC ProtoJL_Eval_String(Eval.p-ascii)
PrototypeC ProtoJL_AtExit_Hook(Status.i)
PrototypeC.d ProtoJL_Unbox_Float64(*jlptr)
PrototypeC.l ProtoJL_Unbox_Int32(*jlptr)
PrototypeC ProtoJL_Box_Float64(num.d)
PrototypeC ProtoJL_TypeOf_Str(*jlptr)

jl_init.ProtoJL_Init = GetFunction(juliaLib,"jl_init")
jl_eval_string.ProtoJL_Eval_String = GetFunction(juliaLib,"jl_eval_string")
jl_atexit_hook.ProtoJL_AtExit_Hook = GetFunction(juliaLib,"jl_atexit_hook")
jl_unbox_float64.ProtoJL_Unbox_Float64 = GetFunction(juliaLib,"jl_unbox_float64")
jl_unbox_int32.ProtoJL_Unbox_Int32 = GetFunction(juliaLib,"jl_unbox_int32")
jl_box_float64.ProtoJL_Box_Float64 = GetFunction(juliaLib,"jl_box_float64")
jl_typeof_str.ProtoJL_TypeOf_Str = GetFunction(juliaLib,"jl_typeof_str")

jl_init()
*j = jl_eval_string("sqrt(2.0)")
sptr = jl_typeof_str(*j)
PrintN(PeekS(sptr,-1,#PB_Ascii))
jrsltf.d = jl_unbox_float64(*j)
PrintN(StrD(jrsltf))
jl_atexit_hook(0)
Wants everything as ASCII. If there is a way to set up the prototype that returns a string as a .s, I can't figure it out. Just treating it as a pointer and getting the string with PeekS.
Post Reply