Skip to content

ccall does not support non-const library names #2316

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
stevengj opened this issue Feb 15, 2013 · 8 comments
Closed

ccall does not support non-const library names #2316

stevengj opened this issue Feb 15, 2013 · 8 comments

Comments

@stevengj
Copy link
Member

For PyCall, I need to determine the Python shared library name at runtime (by calling python and querying its LDLIBRARY), but ccall does not allow the library name to be a non-const variable:

libpython = "libpython2.6"
ccall((:Py_Initialize, libpython), Void, ())

gives ERROR: type: anonymous: in ccall: function argument not a pointer or valid, constant expression, expected BitsKind, got (AbstractKind,)

However, as an ugly hack:

const libpython = ""
libpython = "libpython2.6"
ccall((:Py_Initialize, libpython), Void, ())

seems to sort of work (Julia allows me to modify libpython even though I declared it const, which seems mildly horrifying and likely to break in future versions). But from struggling to use this hack in a module, it seems like it breaks easily even now.

Please provide a way to do this properly.

PS. The more I use ccall the more I hate that it behaves so differently from an ordinary function call. No splicing (#1313), apparently no macros or functions of any kind in some of the arguments, and probably there are other limitations I haven't noticed yet. All of this goofiness seems like a bug to me.

@pao
Copy link
Member

pao commented Feb 15, 2013

A slightly less ugly hack would be to fall back on dlopen, which I don't believe has such a restriction.

@stevengj
Copy link
Member Author

Good point, thanks for the tip! I still find it frustrating that ccall is so unlike most Julia functions in how it handles it arguments, but this is a good workaround.

@vtjnash
Copy link
Member

vtjnash commented Feb 15, 2013

part of the problem with ccall is that a lot of it must be known at compile time to be efficient. the restriction on having the symbol lookup be const is supposed to hint that changing the variable might not have an effect, and would be much slower if allowed (the library name is cached at compile-time for efficiency). it's possible to allow the library to be non-constant, but this would force a call to dlsym every time, since we don't know when or if the library name will ever change.

c-functions jl_wrap_raw_dl_handle(dlopen()) or julia's dlopen and dlsym can be used now for this effect, but require extra work on the part of the programmer to manage the method lookup cache

I'm interested to hear if you have ideas for how to make this easier, without introducing another performance trap

@toivoh
Copy link
Contributor

toivoh commented Feb 15, 2013

Even though the python shared library name is not known until runtime, there's nothing that prevents you from forming the code that needs to know that name afterwards, and then compiling it, e.g. by passing function definitions to eval. That's the beauty of JIT compilation in a homoiconic language: runtime and compile time can be intermixed.

@stevengj
Copy link
Member Author

Fortunately, the dlopen/dlsym stuff, now that I've noticed it, turns out to be fairly easy to use for this purpose, and also allow me to cache the library for repeated calls. I'm going to close this issue for now, but it would be good to document dlopen and dlsym in the section of the manual on calling external C code.

@pao
Copy link
Member

pao commented Feb 15, 2013

Since dlopen/dlsym used to be the only way to use ccall, you can probably recover some text from a prior version of the documentation.

@StefanKarpinski
Copy link
Member

dlopen could also be given an optional argument indicating whether to load symbols globally or not.

@Keno
Copy link
Member

Keno commented Feb 15, 2013

Tk and Cairo have a similar problem, which I solved using this quick hack at the time. We should probably either make it official/document it or think of a better way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants