如何从共享库编辑无序地图

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 函数可能有不同的调用约定(尽管我在实践中从未听说过)

【讨论】:

以上是关于如何从共享库编辑无序地图的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C++ 共享库中隐藏业务对象的实现细节并提供接口

Linux 共享库 c++

CMake:如何从子项目的所有静态库中创建一个共享库?

如何从 Jenkins 工作页面隐藏有关共享库的 Git 信息?

如何从 AppModule 级别的共享库中获取提供的服务?角

如何将 #defines 从 C++ 共享库导出到应用程序