YDLWrap is a Yorick plugin for dynamically calling compiled functions
The interface is fast: I have measured an extra overhead of ~ 15ns (about 15 nanoseconds) on my laptop (Core i7 Q820 at 1.73GHz) for a simple function call like sin(x) compared to the built-in version of the same function.
Here how you can call a function using the symbols compiled into the Yorick excutable itself:
// Load the plugin: #include "dlwrap.i" // Open the executable itself: dll = dlopen(); // Create a function wrapper: dll_sin = dlwrap(dll, DL_DOUBLE, "sin", DL_DOUBLE); // | | | | // | | | `-- argument type // | | `--------- symbol name // | `-------------------- return type // `------------------------- dynamic module // Call the wrapper (like a Yorick function): a = dll_sin(1.25);
Of course, you can use the function wrappers as many times as you want and open a specific dynamic library
First, download the source here: ydlwrap-0.0.2.tar.bz2.
You need two external libraries: one for loading dynamic modules, one for dynamically calling compiled functions.
For loading dynamic modules, you can choose:
sudo apt-get install libltdl-dev
For dynamically calling compiled functions, you must use:
sudo apt-get install libffcall1-dev
To use dlopen, add:
-DHAVE_DLOPEN to macro PKG_CFLAGS in Makefile -ldl to macro PKG_DEPLIBS in Makefile
To use libtool, add:
-DHAVE_LIBTOOL to macro PKG_CFLAGS in Makefile -lltdl -ldl to macro PKG_DEPLIBS in Makefile
To use ffcall, add:
-DHAVE_FFCALL to macro PKG_CFLAGS in Makefile -lavcall to macro PKG_DEPLIBS in Makefile
After having edited the Makefile, use Yorick to update the paths:
yorick -batch make.i
Then compile the package (the install step is optional):
make clean make make install
dlwrap-ffcall-play.${DLL}
for ffcall + Playdlwrap-ffcall-dl.${DLL}
for ffcall + system DLdlwrap-ffcall-ltdl.${DLL}
for ffcall + GNU LibtoolTo dynamically call compiled functions, I have tried to use libffi (http://sourceware.org/libffi) but ffi_prep_cif() raises a SIGFPE (perhaps it lefts some dirt in the floating-point registers) which interrupts Yorick. I could not prevent this by using signal(2) to temporarily ignore SIGFPE. The advantage of libffi would be that it may speedup calling functions (argument parsing can be done only once).
C_INT_OUT
, C_LONG_OUT
, etc. to mean that the argument is the name of a Yorick variable set with an int, a long, etc. on return, the called function takes a pointer to the corresponding type.