我正在使用`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`。
正如你所看到的,两个共享对象的结构相似。
当我尝试调用`ds`对象的`dsMethod`时,我遇到了以下问题。我首先加载的共享对象(`libprofile1.so`)不会加载。实际上,`dlopen()`返回`NULL`。当我在`dlopen`之后读取`dlerror`时,得到以下信息:
``` ./libprofile1.so: undefined symbol: _ZN18DataSource13dsMethod ```
因此,如果我有一个调用`ds->Method`的调用,那么第一个共享对象就不会加载!如果我从源代码中注释掉对`ds->dsMethod`的调用,则我的`libprofile1.so`和`libdatasources.so`都可以正常加载。我看不出第二个SO的方法调用与第一个SO的加载之间有什么联系??
也许我不知道,但是在动态加载一个共享对象时,从已经被动态加载的共享对象加载另一个共享对象有任何限制吗?
顺便提一下,使用
更新:
这些库是在Eclipse中构建的。G++编译器和链接器的选项对于这两个库都是相同的。
以下是G++编译器:
在`main`中,在加载`libprofile1.so`之后,我调用`CreateProfile`方法,该方法返回指向`Profile`类对象(称之为`p`)的指针。然后,我对`p`对象(`p->pMethod`)调用`pMethod`方法。在这个方法中,我动态加载了另一个共享对象(`libdatasources.so`)。
在这个共享对象中,我有一个工厂函数`CreateDataSource`和类`DataSource`。`CreateDataSource`函数创建一个`DataSource`类的实例并返回一个指向它的指针。`DataSource`类有一个方法`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
谢谢您提前阅读。以下是需要翻译的内容:选项,从“项目属性 -> 设置 -> 工具设置”中复制