std::dynamic_lib: start fixing windows implementation

The code compiles and runs under windows now, but I couldn't look up any
symbol from the current executable (dlopen(NULL)), and calling looked
up external function handles doesn't seem to work correctly under windows.
This commit is contained in:
Philipp Brueschweiler
2013-06-15 10:10:49 +02:00
parent eadd83da8b
commit c7013ba1fc
2 changed files with 33 additions and 21 deletions

View File

@@ -42,19 +42,15 @@ impl DynamicLibrary {
/// Lazily open a dynamic library. When passed None it gives a /// Lazily open a dynamic library. When passed None it gives a
/// handle to the calling process /// handle to the calling process
pub fn open(filename: Option<&path::Path>) -> Result<DynamicLibrary, ~str> { pub fn open(filename: Option<&path::Path>) -> Result<DynamicLibrary, ~str> {
let open_wrapper = |raw_ptr| {
do dl::check_for_errors_in { do dl::check_for_errors_in {
unsafe { unsafe {
DynamicLibrary { handle: dl::open(raw_ptr) } DynamicLibrary { handle:
}
}
};
match filename { match filename {
Some(name) => do name.to_str().as_c_str |raw_name| { Some(name) => dl::open_external(name),
open_wrapper(raw_name) None => dl::open_internal()
}, }
None => open_wrapper(ptr::null()) }
}
} }
} }
@@ -74,6 +70,7 @@ impl DynamicLibrary {
} }
#[test] #[test]
#[ignore(cfg(windows))]
priv fn test_loading_cosine () { priv fn test_loading_cosine () {
// The math library does not need to be loaded since it is already // The math library does not need to be loaded since it is already
// statically linked in // statically linked in
@@ -106,13 +103,20 @@ priv fn test_loading_cosine () {
#[cfg(target_os = "freebsd")] #[cfg(target_os = "freebsd")]
mod dl { mod dl {
use libc; use libc;
use path;
use ptr; use ptr;
use str; use str;
use task; use task;
use result::*; use result::*;
pub unsafe fn open(filename: *libc::c_char) -> *libc::c_void { pub unsafe fn open_external(filename: &path::Path) -> *libc::c_void {
dlopen(filename, Lazy as libc::c_int) do filename.to_str().as_c_str |raw_name| {
dlopen(raw_name, Lazy as libc::c_int)
}
}
pub unsafe fn open_internal() -> *libc::c_void {
dlopen(ptr::null(), Lazy as libc::c_int)
} }
pub fn check_for_errors_in<T>(f: &fn()->T) -> Result<T, ~str> { pub fn check_for_errors_in<T>(f: &fn()->T) -> Result<T, ~str> {
@@ -159,11 +163,22 @@ mod dl {
mod dl { mod dl {
use os; use os;
use libc; use libc;
use path;
use ptr;
use str;
use task; use task;
use result::*; use result::*;
pub unsafe fn open(filename: *libc::c_char) -> *libc::c_void { pub unsafe fn open_external(filename: &path::Path) -> *libc::c_void {
LoadLibrary(filename) do os::win32::as_utf16_p(filename.to_str()) |raw_name| {
LoadLibraryW(raw_name)
}
}
pub unsafe fn open_internal() -> *libc::c_void {
let mut handle = ptr::null();
GetModuleHandleExW(0 as libc::DWORD, ptr::null(), &handle as **libc::c_void);
handle
} }
pub fn check_for_errors_in<T>(f: &fn()->T) -> Result<T, ~str> { pub fn check_for_errors_in<T>(f: &fn()->T) -> Result<T, ~str> {
@@ -192,7 +207,9 @@ mod dl {
#[link_name = "kernel32"] #[link_name = "kernel32"]
extern "stdcall" { extern "stdcall" {
fn SetLastError(error: u32); fn SetLastError(error: u32);
fn LoadLibrary(name: *libc::c_char) -> *libc::c_void; fn LoadLibraryW(name: *u16) -> *libc::c_void;
fn GetModuleHandleExW(dwFlags: libc::DWORD, name: *u16,
handle: **libc::c_void) -> *libc::c_void;
fn GetProcAddress(handle: *libc::c_void, name: *libc::c_char) -> *libc::c_void; fn GetProcAddress(handle: *libc::c_void, name: *libc::c_char) -> *libc::c_void;
fn FreeLibrary(handle: *libc::c_void); fn FreeLibrary(handle: *libc::c_void);
} }

View File

@@ -18,11 +18,6 @@ use task;
pub mod at_exit; pub mod at_exit;
// Currently only works for *NIXes
#[cfg(target_os = "linux")]
#[cfg(target_os = "android")]
#[cfg(target_os = "macos")]
#[cfg(target_os = "freebsd")]
pub mod dynamic_lib; pub mod dynamic_lib;
pub mod global; pub mod global;