9

由于一些限制,我被迫在运行时加载用 C 编写的库。第三方为我提供了两个库作为静态存档,我们将其转换为共享对象。我正在使用的应用程序根据一些硬件参数在运行时加载其中一个库。不幸的是,其中一个库主要配置了全局变量。

我已经在使用 dlsym 加载函数引用,但我也可以使用 dlsym 加载对这些全局变量的引用吗?

4

3 回答 3

12

是的,您可以使用 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
于 2011-01-12T16:50:45.463 回答
1

是的,您可以使用dlsym().

于 2011-01-12T16:44:06.427 回答
1

是的,你可以,我实际上更喜欢这样做而不是加载函数。我的标准 IOC 模型就是这样做的。

我更喜欢它,因为:

  • 从 void* 转换为指向对象的指针在技术上比转换为函数指针更安全,尽管显然将 void* 与 dlsym 一起使用的系统必须允许您转换指针。(微软的 GetProcAddress 返回他们自己的指针类型,在这种情况下我认为这是一个更好的选择,因为他们可以在以后根据需要更改它的实际含义)。

  • 因为我在 C++ 中执行此操作,所以我可以强制任何此类导出的对象都派生自一个公共基类,然后我可以将该类中的 dynamic_cast 用于我期望的实际对象。这意味着如果错误不是从后面的类派生的,我可以捕获它,从而在以后保存运行时错误。

于 2011-01-12T17:41:00.420 回答