I have a lib (.so) written in C++. If I do nm mylib.so
I get 00000000000029a0 T _ZN4Bits7fromMemEPhl
(among others).
On the other hand, I have an app written in C, that loads some plugins which are written in C++ (dlopen, dlsym, etc).
If I try to use my lib from my c++ plugin I get undefined symbol: _ZN4Bits7fromMemEPhl
. Why?
EDIT:
This is how I compile my plugins:
$(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
And this is how I compile my main app:
$(TARGET): $(TARGET).o
$(CC) -o $@ $^ -g -Wall -std=gnu99 -ldl -lcrypto -Wl,--export-dynamic
EDIT:
The problem is clear. For some reason my library (cpp-bitstring) isn't linked to my plugin. Where is the piece of code that I'm missing?
When you create your shared object, you have to provide the library dependencies if you want the libraries picked up when loading the plugin dynamically.
Here is a simple Makefile:
plugin.o: CXXFLAGS += -fPIC
main: LDFLAGS += -ldl
all: main plugin.so
plugin.so: plugin.o
$(CXX) $^ -o $@ -shared -lreadline
The main.c
file looks like:
#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;
}
And the plugin.cpp
file looks like:
#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;
}