rustwallet/src/lib.rs
2022-10-23 08:58:24 +08:00

118 lines
3.3 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// lib.rs
//
// 此部分代码主要负责Rust-C两侧的数据内存结构转换提供了C侧的函数接口。注意命名规范
// 在C侧使用时凡是函数名带有 '_cwallet'的,调用过之后都必须用'free_cwallet'释放内存,
// 否则导致内存泄漏
//
use std::ffi::{CStr, CString};
use std::os::raw::c_char;
mod wallet;
use wallet_impl::Wallet;
use crate::wallet::*;
// #[cfg(target_os = "android")]
// mod android;
macro_rules! cchar_to_str{
($p1:expr) => {
{
let s = CStr::from_ptr($p1);
let ps = s.to_str().unwrap();
ps
}
}
}
macro_rules! ostr_to_cchar{
($p1:expr) => {
{
let key = match $p1 {
Some(val) => {
CString::new(val).unwrap()
},
None => CString::new("").unwrap()
};
let c_key: *mut c_char = key.into_raw();
c_key
}
}
}
#[repr(C)]
pub struct CWallet {
pub msg_key: *mut c_char,
pub master_key: *mut c_char,
pub second_key: *mut c_char,
pub backup_key: *mut c_char,
}
#[no_mangle]
pub unsafe extern "C" fn new_wallet(msg: *const c_char) -> CWallet {
println!("generating wallet");
let str = cchar_to_str!(msg);
let rust_wallet = wallet_impl::Wallet::new(str);
println!("rust_wallet: {:?}", &rust_wallet);
convert_to_cwallet(rust_wallet)
}
#[no_mangle]
pub unsafe extern "C" fn restore_wallet(msg: *const c_char) -> CWallet {
println!("generating wallet");
let str = cchar_to_str!(msg);
let rust_wallet = wallet_impl::Wallet::new(str);
println!("rust_wallet: {:?}", &rust_wallet);
convert_to_cwallet(rust_wallet)
}
#[no_mangle]
pub unsafe extern "C" fn free_cwallet(cw: CWallet) {
drop(CString::from_raw(cw.msg_key));
drop(CString::from_raw(cw.master_key));
drop(CString::from_raw(cw.second_key));
drop(CString::from_raw(cw.backup_key));
}
#[no_mangle]
pub unsafe extern "C" fn get_address(cw: CWallet) -> *mut c_char{
let rwallet = convert_to_rwallet(&cw);
println!("rwallet: {:?}", rwallet);
let address = rwallet.get_address();
let address_str = format!("{:?}", address);
let c_address = CString::new(address_str).unwrap();
c_address.into_raw()
}
unsafe fn convert_to_cwallet(rwallet: Wallet) -> CWallet {
// 转换Rust字符串数据为C的字符串并移交ownership
let msgkey = CString::new(rwallet.msg_key).unwrap();
let c_msgkey: *mut c_char = msgkey.into_raw();
let masterkey = CString::new(rwallet.master_key).unwrap();
let c_masterkey: *mut c_char = masterkey.into_raw();
let c_secondkey = ostr_to_cchar!(rwallet.second_key);
let c_backupkey = ostr_to_cchar!(rwallet.backup_key);
let cw = CWallet {
msg_key: c_msgkey,
master_key: c_masterkey,
second_key: c_secondkey,
backup_key: c_backupkey,
};
cw
}
unsafe fn convert_to_rwallet(cwallet: &CWallet) -> Wallet {
let pmsg = cchar_to_str!(cwallet.msg_key);
let pm = cchar_to_str!(cwallet.master_key);
let ps = cchar_to_str!(cwallet.second_key);
let pb = cchar_to_str!(cwallet.backup_key);
Wallet {
msg_key: pmsg.to_string(),
master_key: pm.to_string(),
second_key: Some(ps.to_string()),
backup_key: Some(pb.to_string())
}
}