目前我正在创建某种插件系统。我的程序编写代码,然后编译(参见我的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和不安全。我之前从未做过这样的事情,所以我在做什么不安全的事情吗?另外,有没有“更好”的方法来做到这一点(例如,我不必管理再次关闭句柄)?这可以被视为跨操作系统可移植吗?
Theres是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++