Pastey dlopen/dlsym + c helper lib

/* 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; 
}