質問

My objective is to create a python extension module with boost python. The problem is that when code in the shared library uses dlopen to access symbols within the same library, it fails (details below). It seems like the symbols within the module are not loaded into the symbol table of the python process

I have the following code in a shared library myTest.so

// File 1
extern "C" void target_func() {
    std::cout << "Works!" << std::endl;
}

// File 2
typedef void (*Func) ();
void run() {
    void *handle = dlopen(0, RTLD_NOW | RTLD_GLOBAL)
    Func *method = (Func *)dlsym(handle, "target_func");
    // check if method is NULL and fail
}

Its contained in a boost python module as shown -

BOOST_PYTHON_MODULE(myTest) {
    def("run", run);
}

The above code fails when I import the python module and execute

import myTest
myTest.run()

undefined symbol: target_func

However there is NO problem when I link myTest.so with a main function that calls run as below

int main(int argc, char **argv) {
    run();
}

Output: Works!
役に立ちましたか?

解決

By default, the interpreter will not load extensions in a way that will share symbols across extensions. This can be modified by setting the dlopen() flags used by the interpreter via sys.setdlopenflags(). The documentation states:

To share symbols across extension modules, call as sys.setdlopenflags(dl.RTLD_NOW | dl.RTLD_GLOBAL).


Here is the interpreter loading the extension with default settings:

>>> import myTest
>>> myTest.run()
/usr/bin/python: undefined symbol: target_func

And success occurs after modifying the interpreter's dlopen() flags:

>>> import sys
>>> import dl
>>> sys.setdlopenflags(dl.RTLD_NOW | dl.RTLD_GLOBAL)
>>> import myTest
>>> myTest.run()
Works!
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top