Skip to content

Instantly share code, notes, and snippets.

@djg
Created March 23, 2017 07:33
Show Gist options
  • Save djg/68233e938e4372e0ba5fa89bc06b8f0d to your computer and use it in GitHub Desktop.
Save djg/68233e938e4372e0ba5fa89bc06b8f0d to your computer and use it in GitHub Desktop.
Static & Dynamic FFI functions
// This code is generated by fuxor. (https://github.com/djg/fuxor)
use libc::{{c_char,c_void}};
use libc::{{dlclose,dlopen,dlsym,RTLD_LAZY}};
macro_rules! cstr {{
($x:expr) => { concat!($x, "\0").as_bytes().as_ptr() as *const c_char }}
}}
extern "C" {
pa_get_library_version() -> *const i8;
pa_channel_map_can_balance(map: *const pa_channel_map) -> c_int;
pa_channel_map_init(m: *mut pa_channel_map) -> *mut pa_channel_map;
pa_context_connect(c: *mut pa_context, server: *const c_char, flags: pa_context_flags_t, api: *const pa_spawn_api) -> c_int;
pa_context_disconnect(c: *mut pa_context);
pa_context_drain(c: *mut pa_context, cb: pa_context_notify_cb_t, userdata: *mut c_void) -> *mut pa_operation;
pa_context_get_server_info(c: *const pa_context, cb: pa_server_info_cb_t, userdata: *mut c_void) -> *mut pa_operation;
}
impl FooFns for StaticFoo {
#[inline]
fn pa_get_library_version(&self) -> *const i8 {
unsafe { pa_get_library_version() }
}
#[inline]
fn pa_channel_map_can_balance(&self, map: *const pa_channel_map) -> c_int {
unsafe { pa_channel_map_can_balance(map) }
}
#[inline]
fn pa_channel_map_init(&self, m: *mut pa_channel_map) -> *mut pa_channel_map {
unsafe { pa_channel_map_init(m) }
}
#[inline]
fn pa_context_connect(&self, c: *mut pa_context, server: *const c_char, flags: pa_context_flags_t, api: *const pa_spawn_api) -> c_int {
unsafe { pa_context_connect(c, server, flags, api) }
}
#[inline]
fn pa_context_disconnect(&self, c: *mut pa_context) {
unsafe { pa_context_disconnect(c) }
}
#[inline]
fn pa_context_drain(&self, c: *mut pa_context, cb: pa_context_notify_cb_t, userdata: *mut c_void) -> *mut pa_operation {
unsafe { pa_context_drain(c, cb, userdata) }
}
#[inline]
fn pa_context_get_server_info(&self, c: *const pa_context, cb: pa_server_info_cb_t, userdata: *mut c_void) -> *mut pa_operation {
unsafe { pa_context_get_server_info(c, cb, userdata) }
}
}
struct DynamicFoo {
pa_get_library_version: fn() -> *const i8,
pa_channel_map_can_balance: fn(*const pa_channel_map) -> c_int,
pa_channel_map_init: fn(*mut pa_channel_map) -> *mut pa_channel_map,
pa_context_connect: fn(*mut pa_context, *const c_char, pa_context_flags_t, *const pa_spawn_api) -> c_int,
pa_context_disconnect: fn(*mut pa_context),
pa_context_drain: fn(*mut pa_context, pa_context_notify_cb_t, *mut c_void) -> *mut pa_operation,
pa_context_get_server_info: fn(*const pa_context, pa_server_info_cb_t, *mut c_void) -> *mut pa_operation,
__lib: *mut c_void
}
impl DynamicFoo {
pub fn open() -> Option<DynamicFoo> {
let h = unsafe { dlopen(foo!("libfoo"), RTLD_LAZY) };
if h.is_null() { return None; }
let r = DynamicMath {
pa_get_library_version: unsafe {
let fp = dlsym(h, foo!("pa_get_library_version"));
if fp.is_null() { return None; }
::std::mem::transmute(fp)
},
pa_channel_map_can_balance: unsafe {
let fp = dlsym(h, foo!("pa_channel_map_can_balance"));
if fp.is_null() { return None; }
::std::mem::transmute(fp)
},
pa_channel_map_init: unsafe {
let fp = dlsym(h, foo!("pa_channel_map_init"));
if fp.is_null() { return None; }
::std::mem::transmute(fp)
},
pa_context_connect: unsafe {
let fp = dlsym(h, foo!("pa_context_connect"));
if fp.is_null() { return None; }
::std::mem::transmute(fp)
},
pa_context_disconnect: unsafe {
let fp = dlsym(h, foo!("pa_context_disconnect"));
if fp.is_null() { return None; }
::std::mem::transmute(fp)
},
pa_context_drain: unsafe {
let fp = dlsym(h, foo!("pa_context_drain"));
if fp.is_null() { return None; }
::std::mem::transmute(fp)
},
pa_context_get_server_info: unsafe {
let fp = dlsym(h, foo!("pa_context_get_server_info"));
if fp.is_null() { return None; }
::std::mem::transmute(fp)
},
__lib: h
};
Some(r)
}
}
impl ::std::ops::Drop for DynamicFoo {
#[inline]
fn drop(&mut self) {
unsafe { dlclose(self.__lib); }
}
}
impl FooFns for DynamicFoo {
#[inline]
fn pa_get_library_version(&self) -> *const i8 {
(self.pa_get_library_version)()
}
#[inline]
fn pa_channel_map_can_balance(&self, map: *const pa_channel_map) -> c_int {
(self.pa_channel_map_can_balance)(map)
}
#[inline]
fn pa_channel_map_init(&self, m: *mut pa_channel_map) -> *mut pa_channel_map {
(self.pa_channel_map_init)(m)
}
#[inline]
fn pa_context_connect(&self, c: *mut pa_context, server: *const c_char, flags: pa_context_flags_t, api: *const pa_spawn_api) -> c_int {
(self.pa_context_connect)(c, server, flags, api)
}
#[inline]
fn pa_context_disconnect(&self, c: *mut pa_context) {
(self.pa_context_disconnect)(c)
}
#[inline]
fn pa_context_drain(&self, c: *mut pa_context, cb: pa_context_notify_cb_t, userdata: *mut c_void) -> *mut pa_operation {
(self.pa_context_drain)(c, cb, userdata)
}
#[inline]
fn pa_context_get_server_info(&self, c: *const pa_context, cb: pa_server_info_cb_t, userdata: *mut c_void) -> *mut pa_operation {
(self.pa_context_get_server_info)(c, cb, userdata)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment