使用 dlsym 查找命名空间中符号的符号
Finding symbol with dlsym for symbol in namespace
我有一个要加载的动态库。我定义了一个函数 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
命令找到的符号,但得到了同样的错误。如何使用命名空间加载此符号?
查看此页面以获得更好的解释 (https://en.wikipedia.org/wiki/Name_mangling)。
符号名称在提交到库时被破坏。在 C++ 中,名称重整对命名空间、模板参数(如果有)、函数参数(如果有)进行编码。这将产生奇怪的符号,如 _ZN9Wikipedia7article6formatE
。 C++ mangling 是实现定义的,可能会因编译器而异,因此尝试对其进行解码最多是有风险的。我建议将函数移出命名空间并添加 extern "C"
前缀以强制进行 C-style 名称修改。 C-style 名称修改定义明确、标准且适用于所有编译器。所以
extern "C" int add(int a, int b) {
return a + b;
}
和:
void (*mymath_add) = dlsym(libHandle, "_add");
我有一个要加载的动态库。我定义了一个函数 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
命令找到的符号,但得到了同样的错误。如何使用命名空间加载此符号?
查看此页面以获得更好的解释 (https://en.wikipedia.org/wiki/Name_mangling)。
符号名称在提交到库时被破坏。在 C++ 中,名称重整对命名空间、模板参数(如果有)、函数参数(如果有)进行编码。这将产生奇怪的符号,如 _ZN9Wikipedia7article6formatE
。 C++ mangling 是实现定义的,可能会因编译器而异,因此尝试对其进行解码最多是有风险的。我建议将函数移出命名空间并添加 extern "C"
前缀以强制进行 C-style 名称修改。 C-style 名称修改定义明确、标准且适用于所有编译器。所以
extern "C" int add(int a, int b) {
return a + b;
}
和:
void (*mymath_add) = dlsym(libHandle, "_add");