在我自己的过程中查找符号
作者:互联网
设置如下:
>有一个应用程序A加载liba.so(在编译时链接)
> liba.so导出符号expA
>我既不控制A也不控制liba.so
>应用程序A可以通过dlopen(认为插件体系结构)将我指定的库libmine.so加载到同一进程中
>我需要使用libmine.so中的expA,但不知道如何在不显式链接liba.so的情况下找到它,这是我到目前为止所做的.我认为这在现实世界中是行不通的,因为不能保证该符号与我的本地liba.so副本中的地址相同(或者是?). libmine.so将是开源的,并且不能用A重新编译.
我从来没有做过这样的事情,所以在库加载的细节上还不清楚.例如,如果我尝试从libmine.so中进行dlopen(“ liba.so”),我是否可以获取已加载的库或新副本的句柄?
就如何加载libmine.so而言,我所知道的是它将与RTLD_LAZY一起加载(仅此而已).
任何帮助和指针将不胜感激!
解决方法:
如果使用RTLD_GLOBAL对所有liba.so库进行了倾斜处理,则可以使用dlsym(RTLD_DEFAULT,“ expA”)查找符号,而无需重新打开该库.
如果使用RTLD_LOCAL对liba.so库进行了倾斜处理,那么您将需要在自己的libmine.so中再次使用dlopen获取该库的句柄.请注意以下几点:
If the same library is loaded again with dlopen(), the same file handle is returned. The dl library maintains reference counts for library handles, so a dynamic library is not deallocated until dlclose() has been called on it as many times as dlopen() has succeeded on it. The _init() routine, if present, is only called once. But a subsequent call with RTLD_NOW may force symbol resolution for a library earlier loaded with RTLD_LAZY.
即与库的副本相同.
假设expA是一个函数,则该机制为(伪):int expA(int value):
int (*fpointer)(int) = NULL;
void *handle = dlopen("liba.so", RTLD_LAZY | RTLD_LOCAL);
if (handle != NULL) {
void *symbol = dlsym(handle, "expA");
if (symbol != NULL) {
fpointer = (int (*)(int ))symbol;
}
}
那是伪代码,几乎没有错误处理.
标签:dynamic-library,c-3,linux 来源: https://codeday.me/bug/20191122/2062312.html