Salve,
è tutto il giorno che sto combattendo contro il C.
Per un mio progettino devo fare un modesto sistema a plugin. L'ho pensata in questo modo:
1 - Una qualche interfaccia che definisca le chiamate del plugin.
2 - Svariate librerie dinamiche (i plugin per l'appunto) che implementano l'interfaccia.
Dovrebbe essere semplice, invece...
Il codice di base è il seguente:
Il file plugin_1.cpp che implementa il metodo void a(void)
#include <stdio.h>
void a() {
printf("a - ciao");
}
[/b]
Viene compilato con:
g++ -I. -ldl -Wl,-soname,libplugin_1.so -fPIC -shared -o libplugin_1.so plugin_1.cpp
Il file main.cpp
#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>
#define PATH_LIBRARY "/home/law/Documents/uni/2_anno/2_sem/cg_project/netbeans/libdisplay3D/bin"
#define NAME "plugin_1"
typedef void (*simpleCall_prototype) (void);
simpleCall_prototype simpleCall;
static void * libPointer;
void * loadLibrary(char * name) {
void * libPointer;
char * error;
char * dynlibName=new char[256];
snprintf(dynlibName,256,"%s/lib%s.so",PATH_LIBRARY,name);
fprintf(stderr,"loading %s\n",dynlibName);
libPointer = dlopen(dynlibName,RTLD_LAZY);
fprintf(stderr,"bin_loadBinLibrary: loaded\n");
fprintf(stderr,"bin_loadBinLibrary: looking for error\n");
if ( (error=dlerror()) !=NULL || !libPointer) {
fprintf(stderr,"bin_loadBinLibrary: %s", error);
return NULL;
}
return libPointer;
}
int loadSymbols() {
char * error;
int retval;
simpleCall=(simpleCall_prototype) dlsym(libPointer, "a");
if ( (error=dlerror()) !=NULL || !simpleCall) {
fprintf(stderr,"loadSymbols: %s\n",error);
retval=0;
} else {
fprintf(stderr,"loadSymbols: a() LOADED\n");
retval=1;
}
return retval;
}
int main(int argc, char** argv) {
void * libPointer=loadLibrary(NAME);
if (libPointer) {
if (loadSymbols()) {
fprintf(stderr,"main: symbol loaded\n");
simpleCall();
}
else {
fprintf(stderr,"main: can't load symbol\n");
}
} else {
fprintf(stderr,"main: can't load %s\n library",NAME);
}
return (EXIT_SUCCESS);
}
[/b]
compilato con:
g++ -I. -ldl -L./ -rdynamic -Wall -o main main.cpp
L'output del programma:
law@alisss:~/Documents/uni/2_anno/2_sem/cg_project/netbeans/libdisplay3D/bin$ ./main
loading /home/law/Documents/uni/2_anno/2_sem/cg_project/netbeans/libdisplay3D/bin/libplugin_1.so
bin_loadBinLibrary: loaded
bin_loadBinLibrary: looking for error
loadSymbols: ./main: undefined symbol: a
main: can't load symbol
Ma il simbolo a in realtà è presente come da output di nm:
law@alisss:~/Documents/uni/2_anno/2_sem/cg_project/netbeans/libdisplay3D/bin$ nm libplugin_1.so
000016d8 d DW.ref.__gxx_personality_v0
000015bc a _DYNAMIC
000016b8 a _GLOBAL_OFFSET_TABLE_
w _Jv_RegisterClasses
000004bc T _Z1av
000015ac d __CTOR_END__
000015a8 d __CTOR_LIST__
000015b4 d __DTOR_END__
000015b0 d __DTOR_LIST__
000005a4 r __FRAME_END__
000015b8 d __JCR_END__
000015b8 d __JCR_LIST__
000016dc A __bss_start
w __cxa_finalize@@GLIBC_2.1.3
000004f0 t __do_global_ctors_aux
00000420 t __do_global_dtors_aux
000016d0 d __dso_handle
w __gmon_start__
U __gxx_personality_v0@@CXXABI_1.3
000004b7 t __i686.get_pc_thunk.bx
000016dc A _edata
000016e0 A _end
00000524 T _fini
000003ac T _init
000016dc b completed.5982
00000480 t frame_dummy
000016d4 d p.5980
U printf@@GLIBC_2.0
Non so proprio dove sbattere la testa.
Suggerimenti, consigli, alternative sono molto apprezzate
Ringrazio anticipatamente,
Lawrence