我想说的是,我从来没有使用过动态库,因此我什至可能不了解它们如何正常工作。
我想运行一个完全加载的代码,并在进行一些触发(可能是用户交互)之后,想加载一个特定的库并在该库中执行一个函数。最好事后将其关闭。从本质上讲,允许我在运行时进行更改并重新加载。
这是简单的动态库(称为dynlib.so与主代码位于同一目录中):
int getInt(int arg_0)
{
return (arg_0 + 7);
}
这是主程序:
#include <iostream>
#include <dlfcn.h>
int main() {
void *lib_handle = dlopen("./dynlib.so", RTLD_LAZY | RTLD_NOW);
if (!lib_handle) {
fprintf(stderr, "%s\n", dlerror());
exit(EXIT_FAILURE);
}
typedef int (*func_ptr)(int);
func_ptr func = (func_ptr)dlsym(lib_handle, "getInt");
std::cout << func(13);
dlclose(lib_handle);
}
我正在使用以下命令进行编译:g++ -std = c++ 11 -ldl loadlibtest.cpp -o main。
我捕获的错误是./libshared.so:文件太短在我的
if (!lib_handle) {
中。 最佳答案
这对我来说可以。我已经用dynlib.so编译了
$ gcc dynlib.c -fPIC -shared -o dynlib.so
(显然,您需要使用
extern "C"
将其编译为C或C++,以避免名称困惑)。我需要在
-ldl
调用中将g++
放在源文件之后。gcc:4.8.5; g++:5.3.0
dlsym
可能也会失败,并且从void *强制转换为函数指针在技术上是UB。您应该基于usage snippet from themanpage(针对您的函数进行了修改): dlerror(); /* Clear any existing error */
/* Writing: func = (int (*)(int)) dlsym(handle, "getInt");
would seem more natural, but the C99 standard leaves
casting from "void *" to a function pointer undefined.
The assignment used below is the POSIX.1-2003 (Technical
Corrigendum 1) workaround; see the Rationale for the
POSIX specification of dlsym(). */
*(void **) (&func) = dlsym(handle, "getInt");
if ((error = dlerror()) != NULL) {
fprintf(stderr, "%s\n", error);
exit(EXIT_FAILURE);
}