如何从共享库编辑无序地图
Posted
技术标签:
【中文标题】如何从共享库编辑无序地图【英文标题】:How to edit unordered map from shared library 【发布时间】:2020-12-29 13:36:23 【问题描述】:我需要在无序映射中放置一个函数创建器。我正在尝试添加这样的功能:
mylib.cpp
std::unique_ptr<Strategy> makeAllDefect()
return std::make_unique<AllDefect>();
void g(Factory &a)
a.addCreator("shared", makeAllDefect);
main.cpp:
Factory factory;
void load()
void (*g)(Factory &);
void *handle = dlopen("libAllDefect.so", RTLD_NOW);
if(!handle)
std::cout << "Can't load library" << std::endl;
g = (void (*)(Factory&)) dlsym(handle, "g");
std::cout << g;
g(factory);
库加载正确,但 dlsym 总是返回 nullptr
【问题讨论】:
请去掉'c'标签 在调用dlsym
之后从dlerror
读取输出怎么样。您正试图获得 C++ 损坏函数的 C
符号。使用extern "C"
编译库或使用其他动态加载方法。
【参考方案1】:
问题是 mylib.cpp 中的 g()
函数名称被 C++ 编译器破坏,这意味着它在库中不会有“g”名称,而是类似于“_Z1gR7Factory”的名称。解决这个问题的最简单方法是声明 g()
具有 C 链接,这也将禁用名称修改:
extern "C"
void g(Factory &a)
a.addCreator("shared", makeAllDefect);
您可以通过 Linux 中的 nm
实用程序或类似的工具检查库中的名称。
例如我编译了以下代码:
struct Factory ;
extern "C"
void g( Factory & )
有和没有extern "C"
,这里是 nm 输出:
nm t.o
0000000000000000 T g
nm t.o
0000000000000000 T _Z1gR7Factory
当您声明指向函数的指针时,您希望将其设为 extern "C"
以及理论上 C++ 和 C 函数可能有不同的调用约定(尽管我在实践中从未听说过)
【讨论】:
以上是关于如何从共享库编辑无序地图的主要内容,如果未能解决你的问题,请参考以下文章
如何从 Jenkins 工作页面隐藏有关共享库的 Git 信息?