插件是通过
dlopen
插件使用主程序提供的一些符号,但在加载时,它们不会被库看到。
这是密码
Main.cpp
:
#include "SampleMain.h"
#include <dlfcn.h>
#include <iostream>
#include <map>
#include <string>
typedef std::map<std::string, Service> Services;
static Services services;
extern "C" void AddService( const char * name, Service service ) {
std::cerr << "AddService( " << name << " )" << std::endl;
services[name] = service;
}
int main( void ) {
void * hLib = dlopen( "lib/libsample.so", RTLD_LAZY );
if( hLib ) {
typedef bool ( * RegisterServices )( void );
RegisterServices registerServices =
(RegisterServices)dlsym( hLib, "RegisterServices" );
if( registerServices ) {
if( registerServices()) {
Services::iterator it = services.find( "MyService" );
if( it != services.end()) {
Service service = it->second;
int retCode = service( 0 );
std::cerr << "'MyService' returns " << retCode << std::endl;
}
else {
std::cerr << "'MyService' not found!" << std::endl;
}
}
else {
std::cerr << "Registration failed" << std::endl;
}
}
else {
std::cerr << "dlsym error: " << dlerror() << std::endl;
}
dlclose( hLib );
}
else {
std::cerr << "dlopen error: " << dlerror() << std::endl;
}
return 0;
}
这是密码
SampleLib.cpp
#include "SampleMain.h"
#if defined __linux__
# define API extern "C" __attribute((visibility("default")))
#elif defined WIN32
# define API extern "C" __declspec(dllexport)
#else
# error Unsupported platform
#endif
#include <iostream>
#include <vector>
static int ServiceOffer( void * arg ) {
std::cerr << "ServiceOffer|entry" << std::endl;
std::vector<void *> v;
v.push_back( arg );
v.push_back( arg );
v.push_back( arg );
size_t val = v.size();
std::cerr << "ServiceOffer|exit, val: " << val << std::endl;
return 0;
}
API bool RegisterServices( void ) {
AddService( "MyService", ServiceOffer );
return true;
}
这是你的名字
Makefile
:
run: Main lib/libsample.so
LD_LIBRARY_PATH=./lib ./Main
lib/libsample.so: SampleLib.cpp
g++ -fPIC -shared -o $@ $<
Main: SampleMain.cpp
g++ -fPIC -o $@ $< -ldl
这是执行日志
RTLD_NOW
:
$ make run
g++ -fPIC -o Main SampleMain.cpp -ldl
g++ -fPIC -shared -o lib/libsample.so SampleLib.cpp
LD_LIBRARY_PATH=./lib ./Main
dlopen error: lib/libsample.so: undefined symbol: AddService
这是执行日志
RTLD_LAZY
$ make run
g++ -fPIC -o Main SampleMain.cpp -ldl
LD_LIBRARY_PATH=./lib ./Main
./Main: symbol lookup error: lib/libsample.so: undefined symbol: AddService
我该怎么办
出口
AddService
?