Undefined symbol when loading a library using dlopen

Hello, I'm trying to wrap a C++ library which uses dlopen to load a dynamic library and I don't manage to get rid of an "undefined symbol" error. I tried to simulate my problem with a simpler example so hopefully someone may be able to tell me what I'm doing wrong. I have a file func.cpp which provides 2 functions : func.cpp: int simple(void) { return 12; } int call_lib(void) { int res; void *handle = dlopen("/home/jerome/Test/libDyn.so", RTLD_NOW); if (!handle) { return -1; } dlerror(); char* err = 0; int (*fun_dyn)() = (int (*)())dlsym(handle, "fun_dyn"); if ( (err = dlerror()) != 0 ) { dlclose(handle); return -1; } res = (*fun_dyn)(); dlclose(handle); return res; } It is created like that: $ g++ -Wall -g -fPIC -c -o func.o func.cpp $ ar rcs libFun.a func.o I have a dynamic library which is called from call_lib() which depends on libFun.a: libDyn.cpp: #include "func.hpp" int fun_dyn(void) { return simple(); } It is created like that: $ g++ -Wall -g -fPIC -c -o libDyn.o libDyn.cpp $ g++ -Wall -g -fPIC -shared -o libDyn.so libDyn.o I'm using swig to wrap the libFun.a library with this mylib.i interface file: %module mylib int simple(void); int call_lib(void); Then I'm using this setup.py file to create the Python module: from distutils.core import setup, Extension mylib = Extension("_mylib", sources=['mylib.i'], language="c++", extra_link_args=['-rdynamic'], libraries=["Fun", "dl"], ) setup(name="MyLib", platforms=["Linux"], ext_modules=[mylib], py_modules = ["mylib"]) It's a simplified example but when I compile everything I get this error in Python:
import _mylib _mylib.call_lib() failed to open shared object file /home/jerome/Test/libDyn.so: undefined symbol: simple
If I do a nm _mylib.so I see that the symbol simple is present in the library so I'm wondering why dlopen doesn't see it when it tries to load the library. I know I can recompile libDyn.so to link libFun.a but this would means I would need to recompile all the plugins provided for the library I'm trying to wrap and that's not really a solution for my project. Sorry for the long email. I can provide a tar.gz of the source code if needed. Thanks for your help Jerome

On Tue, Aug 26, 2014 at 5:54 PM, Jerome Fuselier <jerome.fuselier@free.fr> wrote:
Hello,
I'm trying to wrap a C++ library which uses dlopen to load a dynamic library and I don't manage to get rid of an "undefined symbol" error.
I tried to simulate my problem with a simpler example so hopefully someone may be able to tell me what I'm doing wrong.
I have a file func.cpp which provides 2 functions :
func.cpp:
int simple(void) { return 12; }
int call_lib(void) { int res; void *handle = dlopen("/home/jerome/Test/libDyn.so", RTLD_NOW);
if (!handle) { return -1; } dlerror(); char* err = 0; int (*fun_dyn)() = (int (*)())dlsym(handle, "fun_dyn"); if ( (err = dlerror()) != 0 ) { dlclose(handle); return -1; } res = (*fun_dyn)(); dlclose(handle); return res; }
It is created like that: $ g++ -Wall -g -fPIC -c -o func.o func.cpp $ ar rcs libFun.a func.o
I have a dynamic library which is called from call_lib() which depends on libFun.a:
libDyn.cpp:
#include "func.hpp"
int fun_dyn(void) { return simple(); }
It is created like that: $ g++ -Wall -g -fPIC -c -o libDyn.o libDyn.cpp $ g++ -Wall -g -fPIC -shared -o libDyn.so libDyn.o
I'm using swig to wrap the libFun.a library with this mylib.i interface file:
%module mylib
int simple(void); int call_lib(void);
Then I'm using this setup.py file to create the Python module:
from distutils.core import setup, Extension
mylib = Extension("_mylib", sources=['mylib.i'], language="c++", extra_link_args=['-rdynamic'], libraries=["Fun", "dl"], )
setup(name="MyLib", platforms=["Linux"], ext_modules=[mylib], py_modules = ["mylib"])
It's a simplified example but when I compile everything I get this error in Python:
import _mylib _mylib.call_lib() failed to open shared object file /home/jerome/Test/libDyn.so: undefined symbol: simple
If I do a nm _mylib.so I see that the symbol simple is present in the library so I'm wondering why dlopen doesn't see it when it tries to load the library.
I know I can recompile libDyn.so to link libFun.a but this would means I would need to recompile all the plugins provided for the library I'm trying to wrap and that's not really a solution for my project.
I don't think this question really has to do with distutils' role in this. But have you tried declaring extern "C" { int simple(void); } in func.cpp? I think that should do it (to get around C++ name mangling). Best of luck, Erik
participants (2)
-
Erik Bray
-
Jerome Fuselier