Page 1 of 1

Pointer Returned from DLL Call

Posted: Tue Jun 18, 2024 11:00 pm
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!

Re: Pointer Returned from DLL Call

Posted: Wed Jun 19, 2024 8:09 am
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 @ ...

Re: Pointer Returned from DLL Call

Posted: Wed Jun 19, 2024 4:01 pm
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

Re: Pointer Returned from DLL Call

Posted: Wed Jun 19, 2024 4:09 pm
by MGD
In the second case, which I think is correct, do I have to do something to convert back from UTF-8?

Re: Pointer Returned from DLL Call

Posted: Thu Jun 20, 2024 3:23 am
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.