【问题标题】:Finding symbol with dlsym for symbol in namespace使用 dlsym 为命名空间中的符号查找符号
【发布时间】:2019-06-20 19:03:58
【问题描述】:

我有一个要加载的动态库。我已经定义了一个函数add():

#include <iostream>
#include "mymath.h"

#define EXPORT __attribute__((visibility("default")))


EXPORT
int mymath::add(int a, int b) {
    return a + b;
}

此符号位于名为 mymath 的命名空间中:

namespace mymath {
    int add(int, int);
}

我用以下命令编译了这个库:

llvm-g++ -Iinclude -dynamiclib -std=c++17 src/mymath.cpp -current_version 1.0 -compatibility_version 1.0 -fvisibility=hidden -o bin/mymath.dylib

现在我想在另一个程序中使用它,在运行时加载这个符号。我来到以下代码:

#include <iostream>
#include <dlfcn.h>
#include "mymath.h"

int main() {
    const char* libName = "bin/mymath.dylib";
    void *libHandle;
    std::cout << "# main() starts" << std::endl;
    libHandle = dlopen(libName, RTLD_NOW);
    if(libHandle == NULL) {
        std::cerr << "Error opening mymath:\n" << dlerror() << std::endl;;
        return 1;
    }
    void (*mymath_add) = dlsym(libHandle, "mymath:add");
    if(mymath_add == NULL) {
        std::cerr << "Error opening while getting address of mymath::add:\n" << dlerror() << std::endl;;
        return 2;
    }
    std::cout << "# main() exits" << std::endl;
    return 0;
}

运行时出现这个错误

 $ make
clang++ -Wall -Wextra -std=c++17 -g -Iinclude -Llib src/main.cpp -o bin/main
 wgonczaronek  Wiktor-Gonczaronek  ~/Projects/…/macos-pt2  master  ? 
 $ ./bin/main
# main() starts
Error opening while getting address of mymath::add:
dlsym(0x7ffac9402a90, mymath:add): symbol not found

我尝试过使用nm 命令找到的符号,但得到相同的错误。如何使用命名空间加载此符号?

【问题讨论】:

    标签: c++ macos dylib dynamic-library


    【解决方案1】:

    请参阅此页面以获得更好的解释 (https://en.wikipedia.org/wiki/Name_mangling)。

    在库中省略符号名称时,符号名称会被破坏。在 C++ 中,名称修饰对命名空间、模板参数(如果有)、函数参数(如果有)进行编码。这将产生像_ZN9Wikipedia7article6formatE 这样的奇怪符号。 C++ mangling 是实现定义的,并且可能会从编译器更改为编译器,因此尝试对其进行解码充其量是有风险的。我建议将函数移出命名空间并添加 extern "C" 前缀以强制 C 样式名称重整。 C 风格的名称修饰定义良好,是标准的,并且适用于每个编译器。所以

    extern "C" int add(int a, int b) {
        return a + b;
    }
    

    和:

    void (*mymath_add) = dlsym(libHandle, "_add");
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-03-12
      • 1970-01-01
      • 2019-06-02
      • 1970-01-01
      • 1970-01-01
      • 2011-02-01
      • 2016-06-14
      相关资源
      最近更新 更多