Trying to mix libloading and libffi for real dynamic call

Implementing an interpreter. I would like to be able to do truly dynamic calls to the underlying OS.

user would do something like

ext_fn gle("kernel32.dll","GetLastError", "u32", []);
....
var err = gle();

My plan is to use libloading to load the dll/so, then use libffi to call the entry point.

First problem is that I cannot work out how to convert the returned function pointer from libloading into the type expected by raw::ffi_call. I do

  let fun = lib
        .get::<u32>(b"GetLastError")
        .unwrap()
        .into_raw()
        .into_raw()
        .unwrap();

but that creates fun as 'unsafe extern "system" fn() ->isize'

ffi_call wants 'unsafe extern "C" fn()'

I cant work out how to force the cast (or even if that would work)

firstly, you are getting a "wrong" type of the Symbol, it should be a pointer type instead of Symbol<u32>; also, you dont' need the "raw" value of the symbols: the symbol can be deref-ed to its underlying pointer. for example, to get a unsafe extern "C" fn():

// an function pointer type alias for readability
type FP = unsafe extern "C" fn ();
let fp = lib.get::<FP>(b"GetLastError\0").unwrap();
// `Symbol` deref to FP, and function pointers are `Copy`:
let fp: FP = *fp;

I'm not familiar with libffi, just be extra careful when using libloading, it's extremely unsafe by its nature, and you are very likely to run into crashes some way or another.

for example, the Symbol type is a wrapper for the underlying pointer type, it ensures the library is not unloaded thanks to the lifetime. if you by pass the wrapper and use the pointer directly, you must make sure the Library object is not dropped when you call the function pointer.

1 Like

Thank you , very useful pointers. I am fully aware that I am walking on thin ice here :slight_smile:

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.