39 lines
1.0 KiB
Rust
39 lines
1.0 KiB
Rust
#![allow(unused_unsafe)]
|
|
extern crate libc;
|
|
|
|
use std::io::{self,Write};
|
|
use std::{mem,ffi,process};
|
|
|
|
use libc::{c_double, RTLD_NOW};
|
|
|
|
// Small macro which wraps turning a string-literal into a c-string.
|
|
// This is always safe to call, and the resulting pointer has 'static lifetime
|
|
macro_rules! to_cstr {
|
|
($s:expr) => {unsafe {ffi::CStr::from_bytes_with_nul_unchecked(concat!($s, "\0").as_bytes()).as_ptr()}}
|
|
}
|
|
|
|
macro_rules! from_cstr {
|
|
($p:expr) => {ffi::CStr::from_ptr($p).to_string_lossy().as_ref() }
|
|
}
|
|
|
|
fn main() {
|
|
unsafe {
|
|
let handle = libc::dlopen(to_cstr!("libm.so.6"), RTLD_NOW);
|
|
|
|
if handle.is_null() {
|
|
writeln!(&mut io::stderr(), "{}", from_cstr!(libc::dlerror())).unwrap();
|
|
process::exit(1);
|
|
}
|
|
|
|
let extern_cos = libc::dlsym(handle, to_cstr!("cos"))
|
|
.as_ref()
|
|
.map(mem::transmute::<_,fn (c_double) -> c_double)
|
|
.unwrap_or(builtin_cos);
|
|
println!("{}", extern_cos(4.0));
|
|
}
|
|
}
|
|
|
|
fn builtin_cos(x: c_double) -> c_double {
|
|
x.cos()
|
|
}
|