mirror of
https://github.com/openharmony/third_party_rust_libloading.git
synced 2026-07-21 00:26:36 -04:00
214 lines
5.9 KiB
Rust
214 lines
5.9 KiB
Rust
#[cfg(windows)]
|
|
extern crate winapi;
|
|
|
|
extern crate libloading;
|
|
use libloading::{Symbol, Library};
|
|
|
|
const LIBPATH: &'static str = "target/libtest_helpers.module";
|
|
|
|
fn make_helpers() {
|
|
static ONCE: ::std::sync::Once = ::std::sync::Once::new();
|
|
ONCE.call_once(|| {
|
|
let rustc = std::env::var_os("RUSTC").unwrap_or_else(|| { "rustc".into() });
|
|
let mut cmd = ::std::process::Command::new(rustc);
|
|
cmd
|
|
.arg("src/test_helpers.rs")
|
|
.arg("-o")
|
|
.arg(LIBPATH);
|
|
if let Some(target) = std::env::var_os("TARGET") {
|
|
cmd.arg("--target").arg(target);
|
|
} else {
|
|
eprintln!("WARNING: $TARGET NOT SPECIFIED! BUILDING HELPER MODULE FOR NATIVE TARGET.");
|
|
}
|
|
assert!(cmd
|
|
.status()
|
|
.expect("could not compile the test helpers!")
|
|
.success()
|
|
);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn test_id_u32() {
|
|
make_helpers();
|
|
let lib = Library::new(LIBPATH).unwrap();
|
|
unsafe {
|
|
let f: Symbol<unsafe extern fn(u32) -> u32> = lib.get(b"test_identity_u32\0").unwrap();
|
|
assert_eq!(42, f(42));
|
|
}
|
|
}
|
|
|
|
#[repr(C)]
|
|
#[derive(Clone,Copy,PartialEq,Debug)]
|
|
struct S {
|
|
a: u64,
|
|
b: u32,
|
|
c: u16,
|
|
d: u8
|
|
}
|
|
|
|
#[test]
|
|
fn test_id_struct() {
|
|
make_helpers();
|
|
let lib = Library::new(LIBPATH).unwrap();
|
|
unsafe {
|
|
let f: Symbol<unsafe extern fn(S) -> S> = lib.get(b"test_identity_struct\0").unwrap();
|
|
assert_eq!(S { a: 1, b: 2, c: 3, d: 4 }, f(S { a: 1, b: 2, c: 3, d: 4 }));
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn test_0_no_0() {
|
|
make_helpers();
|
|
let lib = Library::new(LIBPATH).unwrap();
|
|
unsafe {
|
|
let f: Symbol<unsafe extern fn(S) -> S> = lib.get(b"test_identity_struct\0").unwrap();
|
|
let f2: Symbol<unsafe extern fn(S) -> S> = lib.get(b"test_identity_struct").unwrap();
|
|
assert_eq!(*f, *f2);
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn wrong_name_fails() {
|
|
Library::new("target/this_location_is_definitely_non existent:^~").err().unwrap();
|
|
}
|
|
|
|
#[test]
|
|
fn missing_symbol_fails() {
|
|
make_helpers();
|
|
let lib = Library::new(LIBPATH).unwrap();
|
|
unsafe {
|
|
lib.get::<*mut ()>(b"test_does_not_exist").err().unwrap();
|
|
lib.get::<*mut ()>(b"test_does_not_exist\0").err().unwrap();
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn interior_null_fails() {
|
|
make_helpers();
|
|
let lib = Library::new(LIBPATH).unwrap();
|
|
unsafe {
|
|
lib.get::<*mut ()>(b"test_does\0_not_exist").err().unwrap();
|
|
lib.get::<*mut ()>(b"test\0_does_not_exist\0").err().unwrap();
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn test_incompatible_type() {
|
|
make_helpers();
|
|
let lib = Library::new(LIBPATH).unwrap();
|
|
unsafe {
|
|
assert!(match lib.get::<()>(b"test_identity_u32\0") {
|
|
Err(libloading::Error::IncompatibleSize) => true,
|
|
_ => false,
|
|
})
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn test_incompatible_type_named_fn() {
|
|
make_helpers();
|
|
unsafe fn get<'a, T>(l: &'a Library, _: T) -> Result<Symbol<'a, T>, libloading::Error> {
|
|
l.get::<T>(b"test_identity_u32\0")
|
|
}
|
|
let lib = Library::new(LIBPATH).unwrap();
|
|
unsafe {
|
|
assert!(match get(&lib, test_incompatible_type_named_fn) {
|
|
Err(libloading::Error::IncompatibleSize) => true,
|
|
_ => false,
|
|
})
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn test_static_u32() {
|
|
make_helpers();
|
|
let lib = Library::new(LIBPATH).unwrap();
|
|
unsafe {
|
|
let var: Symbol<*mut u32> = lib.get(b"TEST_STATIC_U32\0").unwrap();
|
|
**var = 42;
|
|
let help: Symbol<unsafe extern fn() -> u32> = lib.get(b"test_get_static_u32\0").unwrap();
|
|
assert_eq!(42, help());
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn test_static_ptr() {
|
|
make_helpers();
|
|
let lib = Library::new(LIBPATH).unwrap();
|
|
unsafe {
|
|
let var: Symbol<*mut *mut ()> = lib.get(b"TEST_STATIC_PTR\0").unwrap();
|
|
**var = *var as *mut _;
|
|
let works: Symbol<unsafe extern fn() -> bool> =
|
|
lib.get(b"test_check_static_ptr\0").unwrap();
|
|
assert!(works());
|
|
}
|
|
}
|
|
|
|
#[cfg(unix)]
|
|
#[test]
|
|
fn library_this_get() {
|
|
use libloading::os::unix::Library;
|
|
make_helpers();
|
|
let _lib = Library::new(LIBPATH).unwrap();
|
|
let this = Library::this();
|
|
// SAFE: functions are never called
|
|
unsafe {
|
|
// Library we loaded in `_lib` (should be RTLD_LOCAL).
|
|
// FIXME: inconsistent behaviour between macos and other posix systems
|
|
// assert!(this.get::<unsafe extern "C" fn()>(b"test_identity_u32").is_err());
|
|
// Something obscure from libc...
|
|
assert!(this.get::<unsafe extern "C" fn()>(b"freopen").is_ok());
|
|
}
|
|
}
|
|
|
|
#[cfg(windows)]
|
|
#[test]
|
|
fn library_this() {
|
|
use libloading::os::windows::Library;
|
|
make_helpers();
|
|
let _lib = Library::new(LIBPATH).unwrap();
|
|
let this = Library::this().expect("this library");
|
|
// SAFE: functions are never called
|
|
unsafe {
|
|
// Library we loaded in `_lib`.
|
|
assert!(this.get::<unsafe extern "C" fn()>(b"test_identity_u32").is_err());
|
|
// Something "obscure" from kernel32...
|
|
assert!(this.get::<unsafe extern "C" fn()>(b"GetLastError").is_err());
|
|
}
|
|
}
|
|
|
|
#[cfg(windows)]
|
|
#[test]
|
|
fn works_getlasterror() {
|
|
use winapi::um::errhandlingapi;
|
|
use winapi::shared::minwindef::DWORD;
|
|
use libloading::os::windows::{Library, Symbol};
|
|
|
|
let lib = Library::new("kernel32.dll").unwrap();
|
|
let gle: Symbol<unsafe extern "system" fn() -> DWORD> = unsafe {
|
|
lib.get(b"GetLastError").unwrap()
|
|
};
|
|
unsafe {
|
|
errhandlingapi::SetLastError(42);
|
|
assert_eq!(errhandlingapi::GetLastError(), gle())
|
|
}
|
|
}
|
|
|
|
#[cfg(windows)]
|
|
#[test]
|
|
fn works_getlasterror0() {
|
|
use winapi::um::errhandlingapi;
|
|
use winapi::shared::minwindef::DWORD;
|
|
use libloading::os::windows::{Library, Symbol};
|
|
|
|
let lib = Library::new("kernel32.dll").unwrap();
|
|
let gle: Symbol<unsafe extern "system" fn() -> DWORD> = unsafe {
|
|
lib.get(b"GetLastError\0").unwrap()
|
|
};
|
|
unsafe {
|
|
errhandlingapi::SetLastError(42);
|
|
assert_eq!(errhandlingapi::GetLastError(), gle())
|
|
}
|
|
}
|