使用动态链接加载程序的目的 代替直接函数调用?

问题描述 投票:0回答:1

我今天遇到了类似于这段代码的东西。

A.h中:

class A { blah blah blah }

#define CREATE_A_FUNC_NAME   ("CreateA")
extern "C" A* CreateA(void);
typedef A* (*funcCreateA)(void);

main.cpp中:

void* handle = dlopen("libA.so", RTLD_LAZY);
funcCreateA func = (funcCreateA)dlsym(handle, CREATE_A_FUNC_NAME);
A* a = func();

现在显然A.h只是声明的标头,并且其所有实现都存储在libA.so中。

我已经测试过,如果我正确设置了我的项目,这意味着lib已正确链接,我可以简单地执行A* a = CreateA()以获取指向新创建的A实例的指针。因此,这里出现了问题。为什么要通过一个简单的函数调用来完成一些简单的事情呢?这种技术称为什么?优缺点都有什么?我什么时候应该使用这种技术?谢谢!

c++ linux shared-libraries dynamic-linking
1个回答
1
投票

使用dlsym而不是直接链接到DSO的主要原因:

  • [您想为您的应用程序提供插件机制,因此您需要能够动态加载DSO ((构建exe时链接程序不知道插件)。最简单的方法是添加一些虚拟基类(我假设'A'有一些虚拟方法?),然后导出带有“ C”链接的创建者方法(禁用C ++名称修饰)。看来这是这里的意图?
  • [您可能已经为特定的CPU指令集优化了代码(即,在游戏引擎启动时,检查哪个是CPU支持的最新指令集,在运行时加载相关的SSE或AVX库,然后调用方法针对该特定CPU进行了优化)
  • [在极少数情况下,您可能希望“卸载”一些繁重的代码以释放设备上的更多内存。在Android / iOS和控制台(例如,在编译完所有着色器之后释放着色器编译器),这种情况会发生很多。

值得注意的是,如果直接链接到DSO,在后台,链接器将仅在应用程序启动时插入dlsym / dlopen代码,这将自动加载DSO并解析符号。

© www.soinside.com 2019 - 2024. All rights reserved.