Created
June 30, 2014 15:25
-
-
Save LeebDeveloper/38c9a2b7cf169333f9c8 to your computer and use it in GitHub Desktop.
Erlang NIF in pure Rust
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-module(niftest). | |
-export([add/2]). | |
-on_load(init/0). | |
init() -> | |
ok = erlang:load_nif("./nif", 0). | |
add(_, _) -> | |
exit(nif_library_not_loaded). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![crate_id="rusthello#0.0"] | |
#![crate_type="dylib"] | |
extern crate libc; | |
use libc::{c_char,c_void}; | |
use std::c_vec::CVec; | |
//use std::c_str::{CString}; | |
type ErlNifTerm = u32; | |
type ErlNifEnv = *const libc::c_void; | |
#[nolink] | |
extern { | |
fn enif_get_int(env: *const ErlNifEnv, term: ErlNifTerm, ip: *mut i32) -> i32; | |
fn enif_make_int(env: *const ErlNifEnv, i: i32) -> ErlNifTerm; | |
} | |
extern fn add_nif(env: *const ErlNifEnv, argc: i32, argv: *mut ErlNifTerm) -> ErlNifTerm { | |
unsafe { | |
let mut a:i32 = 0; | |
let mut b:i32 = 0; | |
let t = CVec::new(argv, argc as uint); | |
let arguments = t.as_slice(); | |
enif_get_int(env, arguments[0], &mut a); | |
enif_get_int(env, arguments[1], &mut b); | |
enif_make_int(env, a + b) | |
} | |
} | |
#[packed] | |
pub struct ErlNifFunc { | |
name : *const libc::c_char, | |
arity : u32, | |
fptr : extern fn(env: *const ErlNifEnv, argc: i32, argv: *mut ErlNifTerm) -> ErlNifTerm | |
} | |
#[packed] | |
pub struct ErlNifEntry { | |
major : i32, | |
minor : i32, | |
name : *const libc::c_char, | |
num_of_funcs : i32, | |
funcs : *const ErlNifFunc, | |
load : Option<extern "C" fn(env: *const ErlNifEnv, priv_data: *const libc::c_void, load_info: ErlNifTerm) -> i32>, | |
reload : Option<extern "C" fn(env: *const ErlNifEnv, priv_data: *const libc::c_void, load_info: ErlNifTerm) -> i32>, | |
upgrade : Option<extern "C" fn(env: *const ErlNifEnv, priv_data: *const libc::c_void, old_priv_data: *const libc::c_void, load_info: ErlNifTerm) -> i32>, | |
unload : Option<extern "C" fn(env: *const ErlNifEnv, priv_data: *const libc::c_void)>, | |
vm_variant : *const libc::c_char | |
} | |
static mut FunTbl : [ErlNifFunc, ..1] = | |
[ErlNifFunc{ | |
name : 0 as *const libc::c_char, | |
arity : 2, | |
fptr : add_nif | |
}]; | |
static mut NifEntry : ErlNifEntry = ErlNifEntry { | |
major : 2, | |
minor : 4, | |
name : 0 as *const libc::c_char, | |
num_of_funcs : 1, | |
funcs : 0 as *const ErlNifFunc, | |
load : None, | |
reload : None, | |
upgrade : None, | |
unload : None, | |
vm_variant : 0 as *const libc::c_char | |
}; | |
#[no_mangle] | |
pub extern "C" fn nif_init() -> *const ErlNifEntry { | |
unsafe { | |
FunTbl[0].name = "add".to_c_str().unwrap(); | |
NifEntry.name = "niftest".to_c_str().unwrap(); | |
NifEntry.funcs = FunTbl.as_ptr(); | |
NifEntry.vm_variant = "beam.vanilla".to_c_str().unwrap(); | |
let p: *const ErlNifEntry = &NifEntry; | |
p | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment