I have a shared C library with its full name in ENV["LIBSIMC"]
:
julia> ENV["LIBSIMC"]
"/home/paul/st/simc/bin/libsimc.so"
My call works fine with a literal constant, e.g.:
ccall((:logText, "/home/paul/st/simc/bin/libsimc.so"), Cvoid, (Cstring,), "something, something")
but it fails with library name in a String:
julia> ccall((:logText, ENV["LIBSIMC"]), Cvoid, (Cstring,), "something, something")
ERROR: TypeError: in ccall: first argument not a pointer or valid constant expression, expected Ptr, got Tuple{Symbol,String}
How to fix it?
You can’t do that. The name and library to ccall has to be a constant. If there’s no way to determine the name at pre-compilation time, you should use dlopen
and dlsym
manually. I believe PyCall
uses it.
3 Likes
Thank you. I can work around it. I tried a relative path and I was surprised by the failure:
julia> ccall((:shutdown, "~/st/simc/bin/libsimc.so"), Cvoid, ())
ERROR: could not load library "~/st/simc/bin/libsimc.so"
~/st/simc/bin/libsimc.so: cannot open shared object file: No such file or directory
Stacktrace:
[1] top-level scope at ./REPL[2]:1
shell> file ~/st/simc/bin/libsimc.so
/home/paul/st/simc/bin/libsimc.so: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, BuildID[sha1]=e9c5bf2bd0401b726d2a37c3162c93951f6f5736, not stripped
You did not try a relative path. You tried a shell expansion. ~
is the absolute path to your home and it’s a shell function. Relative path does work but it won’t be relative to somewhere you want.
1 Like
For the sake of completeness and as an answer to future searches, here is the way to use a String
for library path:
libPath = pwd()
push!(Base.DL_LOAD_PATH, libPath)
ccall((:logText, "libsimc.so"), Cvoid, (Cstring,), "something, something")
3 Likes