Pastey dlopen/dlsym + c helper lib
- Posted by jimcbrown (admin) Sep 29, 2012
/* compiled with: gcc -o /dev/shm/helper.so -shared /dev/shm/helper.c */ void * topointer(void * p) { return p; } void * caller(void * x, void * p) { void * (*addr)(void *) = (void*(*)(void *))x; return addr(p); } -- euphoria shared object runner include std/dll.e include std/os.e -- sleep include std/console.e include std/machine.e atom dllptr, kernaldll integer thistask, FreeDLL object junk constant --stdlib = open_dll( "/lib/libdl.so.2" ), stdlib = open_dll( "" ), helperlib = open_dll( "/dev/shm/helper.so" ), caller_ = define_c_func( helperlib, "caller", { C_POINTER, C_POINTER }, C_POINTER ), topointer_ = define_c_func( helperlib, "topointer", { E_SEQUENCE }, C_POINTER ), frompointer_ = define_c_func( helperlib, "topointer", { C_POINTER }, E_SEQUENCE ), dlopen_ = define_c_func( stdlib, "dlopen", { C_POINTER, C_INT }, C_POINTER ), dlerror_ = define_c_func( stdlib, "dlerror", { }, C_POINTER ), dlsym_ = define_c_func( stdlib, "dlsym", { C_POINTER, C_POINTER }, C_POINTER ), dlclose_ = define_c_func( stdlib, "dlclose", { C_POINTER }, C_INT ) public function topointer( sequence s ) return c_func( topointer_, { s } ) end function public function frompointer( atom p ) return c_func( frompointer_, { p } ) end function public function caller( atom sym, atom p ) return c_func( caller_, { sym, p } ) end function public function dlopen( sequence file, integer flags ) atom ptr = allocate_string(file, 1) return c_func( dlopen_, { ptr, flags } ) end function public function dlerror( ) return peek_string(c_func( dlerror_, { } )) end function public function dlsym( atom dll, sequence sym ) atom ptr = allocate_string(sym, 1) return c_func( dlsym_, { dll, ptr } ) end function public function dlclose( atom dll ) return c_func( dlclose_, { dll } ) end function --====================================================================================================================== constant RT_LAZY_N_GLOBAL = #101 atom starttime = time() for openloop = 1 to 10000 do dllptr = dlopen("/dev/shm/tasks2.so", RT_LAZY_N_GLOBAL) if dllptr = 0 then puts(1, "Couldn't open tasks2.so\n") -- else puts(1,"opened the dll\n") end if thistask = dlsym(dllptr,"task_hello")--,{E_SEQUENCE},E_SEQUENCE) if thistask = -1 then puts(1, "thistask could not be found!\n") -- else puts(1,"thistask was found\n") end if sequence test = {"kat"} atom ptest = topointer(test) --convert euphoria object to raw c pointer --we can't use c_func(), though we could try call() with some asm glue atom ret = caller(thistask,ptest) junk = frompointer(ret) --convert pointer back into euphoria object --with trace --trace(1) dlclose(dllptr) if openloop = 1 then sleep(5) end if -- note memory use after this one load-unload cycle! end for puts(1,"seconds to load-call-unload DLL 10k times: "&sprintf("%d",time()-starttime)&"\n\n") any_key("press something")
1. Comment by mattlewis Sep 29, 2012
Destructor routine to reduce memory leaks for the translated dll:
int __attribute__ ((destructor)) eu_uninit(){ free( _02[0] ); free( _02 ); DeRefDS( _0switches ); DeRef( _9 ); DeRef( _8 ); DeRef( _5 ); return 0; }
2. Comment by mattlewis Sep 29, 2012
more throrough clean up...465KB leaked
extern void *call_back_arg1; extern void *call_back_arg2; extern void *call_back_arg3; extern void *call_back_arg4; extern void *call_back_arg5; extern void *call_back_arg6; extern void *call_back_arg7; extern void *call_back_arg8; extern void *call_back_arg9; int __attribute__ ((destructor)) eu_uninit(){ free( _02[0] ); free( _02 ); DeRefDS( _0switches ); DeRef( _9 ); DeRef( _8 ); DeRef( _5 ); free( call_back_arg1 ); free( call_back_arg2 ); free( call_back_arg3 ); free( call_back_arg4 ); free( call_back_arg5 ); free( call_back_arg6 ); free( call_back_arg7 ); free( call_back_arg8 ); free( call_back_arg9 ); free( tcb ); return 0; }