dlsym获取 C++ 符号

dlsym() 只能解析 C 符号,不能直接解析 C++ 符号。这是因为 C++ 支持 函数重载,编译器会对符号进行 名称修饰(Name Mangling),而 dlsym() 只能按字符串匹配符号名。


 如何用 dlsym() 获取 C++ 符号?

方法 1:使用 extern "C"

如果你能修改库的源码,可以用 extern "C" 让 C++ 函数使用 C 语言的符号格式:

extern "C" void my_function() {
    // 你的 C++ 代码
}

这样 dlsym() 就能直接找到 my_function


方法 2:手动查找修饰后的符号

如果库是别人提供的,无法修改源码,可以:

  1. nm 命令查看符号:

    nm -D libyourlibrary.so | c++filt

    这会显示 所有导出的符号,并解析 C++ 名称修饰。

  2. dlsym() 里用修饰后的符号名: 例如 nm 结果显示:

    0000000000001234 T _Z10my_functionv

    你可以这样:

    void* handle = dlopen("libyourlibrary.so", RTLD_LAZY);
    auto func = (void(*)())dlsym(handle, "_Z10my_functionv");
    if (func) func();
    

方法 3:用 RTLD_GLOBAL + reinterpret_cast

有些库的 C++ 符号会间接暴露,你可以:

void* handle = dlopen("libyourlibrary.so", RTLD_LAZY | RTLD_GLOBAL);
typedef void (*MyFunctionType)();
MyFunctionType func = reinterpret_cast<MyFunctionType>(dlsym(handle, "_Z10my_functionv"));
if (func) func();

但这样要 确保符号匹配,否则可能崩溃。


方法 4:使用 c++filt 解码 C++ 符号

如果你只知道 C++ 函数原型:

void my_function(int);

你可以用 c++filt 反混淆:

echo '_Z11my_functioni' | c++filt

这能帮你找到正确的符号。


结论

dlsym() 只能解析 C 符号
 解决方法:

  • extern "C"(最简单)

  • nm -D + c++filt 查找修饰符号

  • RTLD_GLOBAL 方式

  • 手动使用 C++ 编译器的符号修饰格式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值