【发布时间】:2010-08-30 14:52:13
【问题描述】:
我正在从main 动态加载(通过dlopen())一个共享对象(名为libprofile1.so)。
在libprofile1.so 中我定义了工厂函数CreateProfile 和类Profile。 CreateProfile 函数创建Profile 类的实例并返回指向它的指针。 Profile 类有一个方法 pMethod。
在main中,加载libprofile1.so后,我调用CreateProfile方法返回指向Profile类对象的指针(调用它p)。
之后,我针对对象p (p->pMethod) 调用pMethod 方法。在这种方法中,我动态加载其他共享对象 (libdatasources.so)。
在这个共享对象中,我有一个工厂函数 CreateDataSource 和类 DataSource。CreateDataSource 函数创建一个 DataSource 类的实例并返回一个指向它的指针。 DataSource 类有方法 dsMethod。
如您所见,两个共享对象的结构相似。
从pMethod 加载libdatasources.so 后,我调用CreateDataSource 方法,它返回一个指向DataSource 类实例的指针,调用它ds。
然后我打电话给dsMethod 的ds 对象
(ds->dsMethod)。
现在,问题来了。
当我尝试调用 ds 对象的 dsMethod 时,我首先加载的共享对象 (libprofile1.so) 不会加载。实际上dlopen() 返回NULL。当我在dlopen 之后阅读dlerror 时,我得到:
./libprofile1.so: undefined symbol: _ZN18DataSource13dsMethod
因此,如果我有一个电话 ds->Method,则不会加载第一个共享对象!
如果我从源注释掉调用ds->dsMethod,那么我的libprofile1.so 和libdatasources.so 将毫无问题地加载。
我没有看到从第二个 SO 调用方法与加载第一个 SO 之间的联系???
也许我不知道,但是从一个也被动态加载的共享对象中动态加载共享对象时是否有任何限制?
顺便说一句,dlopen 与RTLD_NOW|RTLD_GLOBAL 一起使用。我试过RTLD_LAZY,但还是同样的问题。
更新:
库是在 Eclipse 中构建的。两个库的 G++ 编译器和链接器选项相同。
这里是 G++ 编译器:
-O0 -g3 -Wall -c -fmessage-length=0
和 G++ 链接器:
-shared
选项,从Project Properties -> Settings -> Tool Settings粘贴p>
提前致谢。
【问题讨论】:
-
您能否更新您的问题,说明 libprofile1.so 和 libdataresources.so 是如何构建的?
标签: c++ linux shared-libraries