在名称空间中用dlsym查找符号

时间:2019-06-20 19:03:58

标签: c++ macos dylib dynamic-library

我有一个要加载的动态库。我已经定义了一个函数13

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 命令找到的符号,但是得到相同的错误。如何使用命名空间加载该符号?

1 个答案:

答案 0 :(得分:1)

有关详细说明,请参见此页(https://en.wikipedia.org/wiki/Name_mangling)。

符号名称在省略到库时会被篡改。在C ++中,名称处理对名称空间,模板参数(如果有),函数参数(如果有)进行编码。这将产生像_ZN9Wikipedia7article6formatE这样的怪异符号。 C ++改写是实现定义的,并且可能因编译器而异,因此尝试对其进行解码最大有风险。我建议将函数移出命名空间,并添加extern "C"前缀以强制进行C样式名称修饰。 C样式的名称处理定义明确,标准,并且可与所有编译器一起使用。所以

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

和:

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