使用 C 应用程序加载的C++插件中的C++库

Using C++ library from a C++ plugin loaded by a C app

本文关键字:C++ 插件 加载 使用 应用程序      更新时间:2023-10-16

我有一个用C++写的lib(.so)。如果我这样做nm mylib.so我会得到00000000000029a0 T _ZN4Bits7fromMemEPhl(除其他外)。

另一方面,我有一个用C编写的应用程序,它加载了一些用C++编写的插件(dlopen,dlsym等)。

如果我尝试从我的 c++ 插件中使用我的库,我会得到undefined symbol: _ZN4Bits7fromMemEPhl.为什么?

编辑:

这就是我编译插件的方式:

$(PLUGINS_DIR)/%.so: $(PLUGINS_DIR)/%.o
    $(CXX) $^ -o $@ -shared
$(PLUGINS_DIR)/%.o: $(PLUGINS_DIR)/%.cpp
    $(CXX) -c $< -o $@ -g -Wall -std=c++11 -pedantic -lcpp-bitstring -fPIC -I.,-rpath=$(LIBS_DIR)/cpp-bitstring

这就是我编译主应用程序的方式:

$(TARGET): $(TARGET).o
    $(CC) -o $@ $^ -g -Wall -std=gnu99 -ldl -lcrypto -Wl,--export-dynamic

编辑:

问题很明显。由于某种原因,我的库(cpp-bitstring)没有链接到我的插件。我缺少的代码段在哪里?

创建共享对象时,如果您希望在动态加载插件时拾取库,则必须提供库依赖项。

下面是一个简单的生成文件:

plugin.o:       CXXFLAGS += -fPIC
main:   LDFLAGS += -ldl
all:    main plugin.so
plugin.so:      plugin.o
        $(CXX) $^ -o $@ -shared -lreadline

main.c文件如下所示:

#include <dlfcn.h>
#include <assert.h>
int
main (void)
{
    void *p = dlopen("./plugin.so", RTLD_NOW);
    assert(p);
    void (*do_stuff)(void) = dlsym(p, "do_stuff");
    assert(do_stuff);
    do_stuff();
    dlclose(p);
    return 0;
}

plugin.cpp文件如下所示:

#include <iostream>
#include <stdlib.h>
#include <readline/readline.h>
extern "C" void do_stuff (void) {
    while (char *s = readline("> ")) {
        std::cout << "- " << s << std::endl;
        free(s);
    }
    std::cout << std::endl;
}