У меня есть библиотека (.so), написанная на C ++. Если я сделаю 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;
}