从 C 应用程序加载的 C++ 插件使用 C++ 库
Using C++ library from a C++ plugin loaded by a C app
我有一个用 C++ 编写的库 (.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) 没有链接到我的插件。我缺少的那段代码在哪里?
创建共享对象时,如果要在动态加载插件时选择库,则必须提供库依赖项。
这是一个简单的 Makefile:
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;
}
我有一个用 C++ 编写的库 (.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) 没有链接到我的插件。我缺少的那段代码在哪里?
创建共享对象时,如果要在动态加载插件时选择库,则必须提供库依赖项。
这是一个简单的 Makefile:
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;
}