【问题标题】:Why does dlsym fail to find a function in a dynamically loaded library?为什么 dlsym 在动态加载的库中找不到函数?
【发布时间】:2020-12-17 20:29:14
【问题描述】:

this answer 到关于compiling additional code at runtime in C or C++ 的问题之后,我准备了这个主程序

#include <dlfcn.h>
#include <stdlib.h>
#include <iostream>

using namespace std;

int main()
{
    // create library
    system ( "/usr/bin/gcc -fPIC -shared test.cpp -o libtest.so" );

    // load library        
    void* fLib = dlopen ( "./libtest.so", RTLD_LAZY );
    if ( !fLib ) {
        cerr << "Cannot open library: " << dlerror() << '\n';
    }

    if ( fLib ) {
        void ( *fn ) () = reinterpret_cast<void (*)()>(dlsym(fLib, "test"));

        if ( fn ) {
            fn();
        }
        dlclose ( fLib );
    }

    return 0;
}

那应该是把“test.cpp”编译成当前目录下的动态库libtest.so,加载库,在库中找到test函数并调用这个函数,但貌似dlsym找不到该功能,即使它在那里。

这是test.cpp 文件:

#include <iostream>

void test()
{
    std::cout << "TEST" << std::endl;
}

main.cpp 编译时使用

g++ -ldl main.cpp -o main

当我执行它时,什么也没有发生:库已加载但fn 指针不可用,这意味着在libtest.so 中找不到该函数。

如果我用nm -gD 查看libtest.so 中的符号,我会看到测试函数:

nm -gD libtest.so 
                 U __cxa_atexit@@GLIBC_2.2.5
                 w __cxa_finalize@@GLIBC_2.2.5
                 w __gmon_start__
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
0000000000001139 T _Z4testv
                 U _ZNSolsEPFRSoS_E
                 U _ZNSt8ios_base4InitC1Ev
                 U _ZNSt8ios_base4InitD1Ev
                 U _ZSt4cout
                 U _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
                 U _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc

c++filt  _Z4testv
test()

为什么dlsym 找不到test()?如何让它找到测试功能?

【问题讨论】:

  • 我知道重命名是什么(使用 c++filt 对问题中的名称进行了分解),我该如何解决这个问题?有什么具体的东西可以让dlsym 知道这个名字被破坏了吗?
  • 我应该对损坏的名称进行硬编码吗?这听起来不像是一个稳定的解决方案:)
  • 谢谢!稳定:如果函数名的修改方式从一个 gcc 版本更改为下一个版本怎么办?

标签: c++ c


【解决方案1】:

解决方案相当简单:使用C language linkage 导出符号。然后它们就不会被破坏:

extern "C" void test()
{
    std::cout << "TEST" << std::endl;
}

【讨论】:

    猜你喜欢
    • 2016-11-20
    • 2021-01-07
    • 2015-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多