Due to some restrictions I am being forced to load a library written in C at runtime. A third party provides two library to me as static archives which we turn into shared objects. The application I'm working with loads one of the libraries at runtime based on some hardware parameters. Unfortunately one of the libraries is configured largely with global variables.
由于一些限制,我*在运行时加载用C编写的库。第三方为我提供了两个库作为静态存档,我们将其转换为共享对象。我正在使用的应用程序根据一些硬件参数在运行时加载其中一个库。不幸的是,其中一个库主要配置了全局变量。
I am already using dlsym to load function references but can I used dlsym to load references to these global variables as well?
我已经使用dlsym加载函数引用但是我可以使用dlsym来加载对这些全局变量的引用吗?
3 个解决方案
#1
10
Yes, you can use dlsym to access globals (as long as they are exported, and not static). The example below is in C++ and Mac, but obviously C will work fine.
是的,您可以使用dlsym来访问全局变量(只要它们被导出,而不是静态)。下面的例子是在C ++和Mac中,但显然C可以正常工作。
lib.cpp:
extern "C" {
int barleyCorn = 12;
}
uselib.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;
}
Output:
% ./a.out
12
#2
1
Yes, you can locate any exported symbol in the dynamic library using dlsym()
.
是的,您可以使用dlsym()在动态库中找到任何导出的符号。
#3
1
Yes you can and I actually prefer to do this rather than load functions. My standard IOC model does it that way.
是的,你可以,我实际上更喜欢这样做,而不是加载功能。我的标准IOC模型就是这样做的。
I prefer it because:
我更喜欢它,因为:
-
The cast from a void* to a pointer to an object is technically safer than that to a function pointer, although obviously the system that uses void* with dlsym must allow you to convert the pointer. (Microsoft's GetProcAddress returns their own pointer type, which in this case I think is a better choice because they can change the actual meaning of this later if they need to).
从void *转换为指向对象的指针在技术上比函数指针更安全,尽管显然使用void * with dlsym的系统必须允许转换指针。 (Microsoft的GetProcAddress返回它们自己的指针类型,在这种情况下,我认为这是一个更好的选择,因为如果需要,它们可以在以后改变它的实际含义)。
-
Because I do it in C++ I can enforce that any such exported object derives from a common base class, and then I can use dynamic_cast from that class to the actual one I expect it to be. This means I can catch an error if it does not derive from the later class, saving runtime errors later.
因为我在C ++中这样做,我可以强制执行任何这样的导出对象派生自一个公共基类,然后我可以使用该类中的dynamic_cast到我期望的实际类。这意味着如果它不是从后面的类派生的话我可以捕获错误,以后会保存运行时错误。
#1
10
Yes, you can use dlsym to access globals (as long as they are exported, and not static). The example below is in C++ and Mac, but obviously C will work fine.
是的,您可以使用dlsym来访问全局变量(只要它们被导出,而不是静态)。下面的例子是在C ++和Mac中,但显然C可以正常工作。
lib.cpp:
extern "C" {
int barleyCorn = 12;
}
uselib.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;
}
Output:
% ./a.out
12
#2
1
Yes, you can locate any exported symbol in the dynamic library using dlsym()
.
是的,您可以使用dlsym()在动态库中找到任何导出的符号。
#3
1
Yes you can and I actually prefer to do this rather than load functions. My standard IOC model does it that way.
是的,你可以,我实际上更喜欢这样做,而不是加载功能。我的标准IOC模型就是这样做的。
I prefer it because:
我更喜欢它,因为:
-
The cast from a void* to a pointer to an object is technically safer than that to a function pointer, although obviously the system that uses void* with dlsym must allow you to convert the pointer. (Microsoft's GetProcAddress returns their own pointer type, which in this case I think is a better choice because they can change the actual meaning of this later if they need to).
从void *转换为指向对象的指针在技术上比函数指针更安全,尽管显然使用void * with dlsym的系统必须允许转换指针。 (Microsoft的GetProcAddress返回它们自己的指针类型,在这种情况下,我认为这是一个更好的选择,因为如果需要,它们可以在以后改变它的实际含义)。
-
Because I do it in C++ I can enforce that any such exported object derives from a common base class, and then I can use dynamic_cast from that class to the actual one I expect it to be. This means I can catch an error if it does not derive from the later class, saving runtime errors later.
因为我在C ++中这样做,我可以强制执行任何这样的导出对象派生自一个公共基类,然后我可以使用该类中的dynamic_cast到我期望的实际类。这意味着如果它不是从后面的类派生的话我可以捕获错误,以后会保存运行时错误。