如何在运行时加载C++函数和类

本文探讨了在C++中如何在运行时加载库、函数和类。C++的名称修饰使得直接加载变得复杂,但通过使用`extern "C"`可以解决函数加载问题。对于类的加载,文章建议使用多态基类和助手函数来创建和销毁对象。给出了具体的代码示例,以帮助理解如何在运行时加载和使用C++类。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

如何在运行时加载C++函数和类

标签(空格分隔): 编程


Problem

有些时候你想在运行时加载一个lib或者function or class,这种事情经常发生在你开发一个plugin或者module时遇到。

在C语言里,你可以轻松的利用dlopen, dlsym, dlclose来做到,但是在C++的世界里却没那么简单了。困难就在C++语言的name mangling上,还有一部分就是dlopen函数是用纯C语言写的,不提供load classes功能。

在解析如何load function和class在c++语言中之前,还是线弄清问题吧---name mangling。

C++ Name Mangling

在C++程序里(或lib or object file中),所有的non-static functions都是以二进制文件symbols来表示。这些symbols都是些特殊的文本字符串,都是唯一的在程序中,lib中活着object file中来标示一个文件。

然而在C语言中,函数的symbol名字就是函数名字本身,例如strcpy的symbol就是strcpy,所以在C语言中不会有中non-static函数出现重名情况。

由于C++有很多C语言没有的功能,例如class,函数的overloading,异常处理等等,所以symbol不可能简单的以函数名来定。为了解决这个问题,C++提出了name mangling,这个name mangling的功能就是把function的名字转换成只有compiler知道的奇怪字符串,利用该函数所有的已知信息,如果函数参数的类型,个数,函数等等,所有如果函数名字为foo(int, char),利用name mangling之后,其名字可能是foo_int_char或者其他字符串也说不定。

现在的问题是在C++标准里(ISO14882)中还没有定义这个function name是被怎样的mangled的,每个编译器都有自己的一套方法。

Classes

另外一个问题就是dlopen函数仅支持load 函数,不支持load class。

很明显的是如果你想使用该class,就需要new instance出来。

Solution

extern “C”

C++有个特殊的关键字来声明函数用C的方式来绑定——extern “C”,在C++中函数如果用extern “C”在前面声明的话,就表示该函数的symbol以C语言方式来命名。

所以只有非成员函数可以用extern “C”来声明,而且他们不能被重载。
虽然很局限,但是这样足够利用dlopen来运行时调用function了。需要强调的是用extern “C”不是就不可以在function内写C++ 代码,依然可以调用class和class的function的。

Loading functions

用dlsym,加载C++函数就像加载C函数一样,你要加载的函数必须要用extern “C”来声明,避免name mangling。
Example 1: load a function

#include <iostream>
#include <dlfcn.h>
int main() {
    using std::cout;
    using std::cerr;
    cout << "C++ dlopen demo\n\n";
    // open the library
    cout << 
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值