1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
#[link(name = "dlopen",
vers = "0.0.1",
uuid = "c6a5758b-9b45-41fd-a935-f3cb7251b4eb",
url = "https://github.com/doy/rust-dlopen")];
#[crate_type = "lib"];
pub use os::Library;
#[cfg(target_os = "linux")]
#[cfg(target_os = "android")]
#[cfg(target_os = "freebsd")]
#[cfg(target_os = "macos")]
mod os {
use core::libc::{c_char,c_int,c_void};
pub struct Library(*c_void);
struct Function(*c_void);
impl Library {
pub fn open (name: &str) -> Library {
do str::as_c_str(libname(name)) |c_name| {
let lib = unsafe { dlopen(c_name, 0) };
if lib == ptr::null() {
fail!(unsafe { str::raw::from_c_str(dlerror()) })
}
else {
Library(lib)
}
}
}
pub fn get_fn (&self, name: &str) -> Function {
unsafe { dlerror() };
do str::as_c_str(name) |c_name| {
let Library(lib) = *self;
let fun = unsafe { dlsym(lib, c_name) };
let err = unsafe { dlerror() };
if err == ptr::null() {
fail!(unsafe { str::raw::from_c_str(err) })
}
else {
Function(fun)
}
}
}
}
impl Drop for Library {
fn finalize (&self) {
let Library(lib) = *self;
unsafe { dlclose(lib) };
}
}
impl Function {
fn call0<A>(&self) -> A {
let Function(fun) = *self;
// XXX how do you call a c function pointer from rust?
let c_fun = unsafe { cast::transmute(fun) };
c_fun()
}
}
#[cfg(target_os = "linux")]
#[cfg(target_os = "android")]
#[cfg(target_os = "freebsd")]
fn libname (name: &str) -> ~str {
fmt!("lib%s.so", name)
}
#[cfg(target_os = "macos")]
fn libname (name: &str) -> ~str {
fmt!("lib%s.dylib", name)
}
#[link_name = "dl"]
extern "C" {
fn dlopen (filename: *c_char, flag: c_int) -> *c_void;
fn dlerror () -> *c_char;
fn dlsym (handle: *c_void, symbol: *c_char) -> *c_void;
fn dlclose (handle: *c_void) -> c_int;
}
}
#[cfg(target_os = "win32")]
mod os {
use core::libc::{BOOL,DWORD,HMODULE,LPCTSTR};
struct FARPROC(*c_void);
pub struct Library(HMODULE);
struct Function(FARPROC);
impl Library {
pub fn open (name: &str) -> Library {
fail!();
}
pub fn get_fn (&self, name: &str) -> Function {
fail!();
}
}
impl Drop for Library {
fn finalize (&self) {
fail!();
}
}
impl Function {
fn call0<A>(&self) -> A {
fail!();
}
}
fn libname (name: &str) -> ~str {
fmt!("%s.dll", name)
}
extern "C" {
fn LoadLibrary(filename: LPCTSTR) -> HMODULE;
fn GetLastError() -> DWORD;
fn GetProcAddress(hModule: HMODULE, lpProcName: LPCTSTR) -> FARPROC;
fn FreeLibrary(hModule: HMODULE) -> BOOL;
}
}
|