brenhinkeller / StaticTools.jl

Enabling StaticCompiler.jl-based compilation of (some) Julia code to standalone native binaries by avoiding GC allocations and llvmcall-ing all the things!
MIT License
167 stars 12 forks source link

StaticTools.dlopen returns Ptr{StaticTools.DYLIB} @0x0000000000000000 #15

Closed mdmaas closed 2 years ago

mdmaas commented 2 years ago

I'm calling a C shared library, and I found that I can't use StaticTools.dlopen and have to rely on Libdl.dlopen instead.

I think the problem is that StaticTools.dlopen returns Ptr{StaticTools.DYLIB} @0x0000000000000000.

Subsequent call to StaticTools.dlopen returns Ptr{Nothing} @0x0000000000000000.

And eventually static compilation crashes.

Minimal example I could come up with:

using StaticTools, StaticCompiler, Libdl

### Let's define a C function
C_code= """
       double mean(double a, double b) {
         return (a+b) / 2;
       }
       """
Clib=tempname()
open(`gcc -fPIC -O3 -xc -shared -o $(Clib * "." * Libdl.dlext) -`, "w") do f
    print(f, C_code)
end

# This doesn't work
lib = StaticTools.dlopen(Clib)
mean = StaticTools.dlsym(lib, c"mean")

# This works
lib = Libdl.dlopen(Clib)
mean = Libdl.dlsym(lib, "mean")

function call_mean(a,b)
    ra, rb = Ref(a), Ref(b)
    GC.@preserve ra rb begin
        pa, pb = pointer_from_objref(ra), pointer_from_objref(rb)
        return @ptrcall mean(pa::Ptr{Nothing}, pb::Ptr{Nothing})::Float64
    end
end

call_mean(2.1,1.2) 
brenhinkeller commented 2 years ago

Thanks for the issue! It looks like the problem may just be that the variable Clib doesn't include the extension, and that Libdl.dlopen apparently auto-appends it when missing but StaticToold.dlopen doesn't

brenhinkeller commented 2 years ago

You can add manually it with StaticTools.DLEXTwhich is the equivalent of Libdl.dlext (so, e.g., Clib * StaticTools.DLEXT if Clib is a StaticString or Clib * Libdl.dlext else) but to match functionality of Libdl I might also be able to check and append automatically

mdmaas commented 2 years ago

Great, this is a minor issue indeed. Matching the API of Libdl sounds like a reasonable idea.