如何从C ++调用动态库函数?

时间:2019-03-28 09:02:05

标签: c++ shared-libraries dlopen

当前,我正在创建某种插件系统。我的程序编写代码,然后将其编译(另请参见我的other问题)。然后使用dlopen重新打开生成的(编译的)库。这使人们可以自己在程序中编写自定义功能。

//Open the compiled library at the specified path
void* handle = dlopen("COMPILEDLIBRARYPATH", RTLD_LAZY);
if (handle == NULL) {
    std::cout << "plugin not found" << std::endl;
}

//Find the function pointer and cast is to std::function (is this good practice??)
std::function<void(float[])> fun = (void (*)(float[]))dlsym(handle, "testFunc");
if (fun == NULL) {
    std::cout << "function not found" << std::endl;
}

float test[3] = {0.0, 0.0, 0.0};
std::cout << "calling plugin" << std::endl;
fun(test);

//Output the result of the call
std::cout << test[0] << " " << test[1] << " " << test[2] << " returned by function" << std::endl;

//Close handle again
if (dlclose(handle) != 0) {
    std::cout << "could not close function" << std::endl;
}

这可以按预期工作,但也感觉有些hacky和不安全。我以前从未做过这样的事情,所以我在这里做任何不安全的事情吗?另外,是否有一种“更好”的方法来执行此操作(例如,在我不必再次关闭手柄的情况下)?可以认为它可以跨操作系统移植吗?

1 个答案:

答案 0 :(得分:0)

dlclose(void *handle)用于关闭手柄。也喜欢将reinterpret_cast用作原始函数指针,而不是将C样式强制转换为std::function

带有dlfcn.h

dlopen和它的朋友是POSIX / UNIX API,因此它可能可以在Solaris,Linux,* BSD,macOS等系统上运行。在Windows上,等效于dlysym的是GetProcAddress中的<windows.h>

以下是有关动态加载的完整文章,可能会有所帮助:https://en.wikipedia.org/wiki/Dynamic_loading#In_C/C++