How Julia call Pybind11 code?

Pybind11 code :

#include <pybind11/embed.h>
#include
namespace py = pybind11;
extern “C”{
int init() {
py::scoped_interpreter python;
auto math = py::module::import(“math”);
double root_two = math.attr(“sqrt”)(2.0).cast();
std::cout << "The square root of 2 is: " << root_two << “\n”;
} }

I will generate a dynamic library libtest.so by using the above code and link to libpython3.7m.so. However, when Julia uses “ccall” method to call libtest.so, math.cpython-37m-x86_64-linux-gnu.so cannot link to libpython3.7m.so and generates error like this undefined symbol: PyArg_Parse. But when c language call libtest.so ,there is no problem. I don’t know why math.cpython-37m-x86_64-linux-gnu.so cannot link to libpython3.7m.so directly when using julia language. And how to solve this problem?

As I said in the github issue, please quote your code.


I believe the issue is in general python modules don’t link libpython presumably to avoid pulling in a different one than the one loading the module with the assumption that the loading process already has libpython loaded.

But IIRC on linux julia use RTLD_LOCAL by default, meaning the symbol from libpython aren’t in the global scope and the module can’t find it. The solution is that you have to directly or indirectly dlopen libpython with RTLD_GLOBAL. If your library is linked to python, dlopening your library should be enough.


As an aside, I think linux has a extension that allow application to load libraries into it’s own namespace. If python uses that this probably won’t be an issue anymore… (edit: hmmm, actually that seems to be the default behavior and RTLD_LOCAL does not seem to be the same as a new namespace…)