由于一些限制,我被迫在运行时加载用 C 编写的库。第三方为我提供了两个库作为静态存档,我们将其转换为共享对象。我正在使用的应用程序根据一些硬件参数在运行时加载其中一个库。不幸的是,其中一个库主要配置了全局变量。
我已经在使用 dlsym 加载函数引用,但我也可以使用 dlsym 加载对这些全局变量的引用吗?
是的,您可以使用 dlsym 访问全局变量(只要它们是导出的,而不是静态的)。下面的示例是在 C++ 和 Mac 中,但显然 C 可以正常工作。
lib.cpp:
extern "C" {
int barleyCorn = 12;
}
使用lib.cpp
#include <dlfcn.h>
#include <iostream>
using namespace std;
main()
{
void * f = dlopen ("lib.dylib", RTLD_NOW);
void * obj = dlsym (f, "barleyCorn");
int * ptr = (int *) obj;
cout << *ptr << endl;
}
输出:
% ./a.out
12
是的,您可以使用dlsym()
.
是的,你可以,我实际上更喜欢这样做而不是加载函数。我的标准 IOC 模型就是这样做的。
我更喜欢它,因为:
从 void* 转换为指向对象的指针在技术上比转换为函数指针更安全,尽管显然将 void* 与 dlsym 一起使用的系统必须允许您转换指针。(微软的 GetProcAddress 返回他们自己的指针类型,在这种情况下我认为这是一个更好的选择,因为他们可以在以后根据需要更改它的实际含义)。
因为我在 C++ 中执行此操作,所以我可以强制任何此类导出的对象都派生自一个公共基类,然后我可以将该类中的 dynamic_cast 用于我期望的实际对象。这意味着如果错误不是从后面的类派生的,我可以捕获它,从而在以后保存运行时错误。