【问题标题】:Why do we have to always resolve the function or symbol in shared object while loading shared library on runTime为什么我们必须在运行时加载共享库时总是解析共享对象中的函数或符号
【发布时间】:2016-09-04 15:13:16
【问题描述】:

我通过How to load a dynamic library on demand from a C++ function/Qt method

似乎我们必须在运行时加载共享库。我们总是编写代码来解析共享对象中的函数/符号名称,使用

1) dlsym ,如果我们在运行时使用 dlopen 加载共享库。或者

2) How to load a dynamic library on demand from a C++ function/Qt method中提出的其他技术

3) 由于我的共享库将有数百万个符号/函数,例如我的共享库有函数

fun1() , fun2 ..... fun1000000

是否有任何直接的方法,我们不需要编写任何代码来解析函数/符号名称,只需在加载共享库后直接从共享库函数中调用函数。

我正在寻找的算法

void loadSharedObject() {  
    //load the
    // Call the function names directly
    // no extra code for resolving the function /symbols names   
    // for example  
     fun1()
     fun2()
 }

【问题讨论】:

  • 如果你的库嵌入了QObject,你可以使用它的元对象机制来获取和调用它的函数。否则,您必须解析 ELF 结构(Linux 上的 readelf)并使用 dlsym(这可能很棘手)。
  • 你为什么要关心这些?你想解决什么问题?你似乎在打一场似乎没有其他人在打的艰苦战斗,这对你来说是不是敲响了警钟?你太努力了。这是不必要的。

标签: qt linker tcl shared-libraries system-calls


【解决方案1】:

如果你像这样直接调用符号,你只是在做普通的链接。这就是普通链接可以实现的。通过动态加载库,您可以在链接阶段之后发现符号——偶尔非常有用——但代价是执行加载的程序无法直接谈论符号。相反,您必须执行dlopen()dlsym() 才能打开一个库并获取对其中符号的引用,但这些引用只是原始指针;您必须应用正确的强制转换将它们转换为具有正确签名的函数指针,然后您可以通过函数指针调用它们。

(Windows 使用不同的 API — LoadLibraryEx()GetProcAddress() — 但它们所做的一般事情是等效的。)

可以将符号引用保存在本地或文件本地变量中。这行得通,然后您可以假装这些符号 正如您在本地命名的那样 可以像任何其他函数一样调用。您可能想使用typedef 来定义函数的类型签名;函数类型在 C 和 C++ 中有点难看。

下面的代码缺少错误处理,特别是,您必须检查dlopen()dlsym() 是否有效,否则如果出现故障,您将遇到严重崩溃.

typedef int (thefunc_t)(int x, int y);

void *handle = dlopen(libraryname, RTLD_LOCAL);
void *sym = dlsym(handle, "thefunc");
thefunc_t *thefunc = reinterpret_cast<thefunc_t *>(sym);

// Now, assuming everything worked, you can just call it like this:
int z = thefunc(1, 2);

【讨论】:

  • 是的,您可以将它们组成一个数组。这并不难。但是,您正在加载的代码需要使用 extern "C" 约定,因为对 C++ 函数名称的去修饰充其量是棘手的(而且移植性也不是很好)。
  • 当我们链接共享库并运行可执行文件时,如何解析共享库的符号以及解析共享库符号的系统调用是什么。如果您可以向我指出链接器是如何工作的文档,这也会很有帮助。链接器共享库时符号如何解析
猜你喜欢
  • 2020-02-25
  • 1970-01-01
  • 2011-04-25
  • 2013-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多