开发流程
在DevEco Studio的模板工程中包含使用Native API的默认工程,使用File->New->Create Project创建Native C++模板工程。
在此基础上进行修改
删除
entry/src/main/cpp
打开
entry/build-profile.json5
删除c++ build 配置
{
"apiType": "stageMode",
"buildOption": {
// "externalNativeOptions": {
// "path": "./src/main/rust/CMakeLists.txt",
// "arguments": "",
// "cppFlags": "",
// }
},
"targets": [
{
"name": "default",
"runtimeOS": "HarmonyOS"
},
{
"name": "ohosTest",
}
]
}
创建rust项目
cargo new hello
修改 Cargo.toml
[package]
name = "hello"
version = "0.1.0"
edition = "2021"
[lib]
name = "hello"
crate-type = ["dylib"]
[dependencies]
oh-napi-sys = "0.1"
ctor = "0.1"
lib.rs 添加测试代码
usestd::ffi::{CString};usestd::ptr::{null_mut};useoh_napi_sys::*;usector::ctor;extern"C"fnadd(env: napi_env, info: napi_callback_info)->napi_value{// 期望从ArkTS侧获取的参数的数量,napi_value可理解为ArkTS value在Native方法中的表现形式。letmut args:[napi_value;2]=[null_mut();2];letmut argc = args.len();unsafe{napi_get_cb_info(env, info,&mut argc, args.as_mut_ptr(),null_mut(),null_mut());letmut valuetype0 = napi_valuetype_napi_undefined;napi_typeof(env, args[0],&mut valuetype0);letmut valuetype1 = napi_valuetype_napi_undefined;napi_typeof(env, args[1],&mut valuetype1);if(valuetype0 != napi_valuetype_napi_number)||(valuetype1 != napi_valuetype_napi_number){letmut undefined: napi_value=null_mut();napi_get_undefined(env,&mut undefined);return undefined;}// 将获取的ArkTS参数转换为Native信息,此处ArkTS侧传入了两个number,这里将其转换为Native侧可以操作的double类型。letmut value0 =0f64;napi_get_value_double(env, args[0],&mut value0);letmut value1 =0f64;napi_get_value_double(env, args[1],&mut value1);// Native侧的业务逻辑,这里简单以两数相加为例。let native_sum = value0 + value1;// 此处将Native侧业务逻辑处理结果转换为ArkTS值,并返回给ArkTS。letmut sum =null_mut();napi_create_double(env, native_sum,&mut sum);return sum;}}typeCallback=extern"C"fn(env: napi_env, info: napi_callback_info)-> napi_value;unsafefnnew_func_descriptor(name:&'staticstr, f:Callback)->napi_property_descriptor{let name=CString::new(name).unwrap();
napi_property_descriptor{
utf8name:CString::into_raw(name),
name:null_mut(),
method:Some(f),
getter:None,
setter:None,
value:null_mut(),
attributes: napi_property_attributes_napi_default,
data:null_mut(),}}// 注册 module#[ctor]fnregister_hello_module(){let name=CString::new("hello").unwrap();letmut hello_module = napi_module{
nm_version:1,
nm_flags:0,
nm_filename:null_mut(),
nm_register_func:Some(init),
nm_modname: name.as_ptr()as _,
nm_priv:0as*mut _,
reserved:[0as*mut _;4],};unsafe{napi_module_register(&mut hello_module);}// Init将在exports上挂上Add/NativeCallArkTS这些Native方法,此处的exports就是开发者import之后获取到的ArkTS对象。unsafeextern"C"fninit(env: napi_env , exports: napi_value )-> napi_value {let desc =[new_func_descriptor("add", add),];let count = desc.len();napi_define_properties(env, exports, count, desc.as_ptr());return exports;}}
添加对应ts代码
// entry/src/main/rust/types/libhello/index.d.tsexportconstadd:(a:number, b:number)=>number;
// entry/src/main/rust/types/libhello/oh-package.json5{"name":"libhello.so","types":"./index.d.ts","version":"","description":"Please describe the basic information."}
配置依赖
// entry/oh-package.json5{"name":"entry","version":"1.0.0","description":"Please describe the basic information.","main":"","author":"","license":"","dependencies":{"libhello.so":"file:./src/main/rust/types/libhello"}}
在 rust 根目录下编译,添加ohos目标的教程可以参考 Rust交叉编译OpenHarmony应用动态库
cargo build -Zbuild-std --release--target aarch64-unknown-linux-ohos
将编译好的
libhello.so
拷贝至
entry/libs/arm64-v8a
修改页面
Index.ets
import testNapi from'libhello.so'// onClick 里添加
hilog.info(0x0000,'testTag','Test NAPI 2 + 3 = %{public}d', testNapi.add(2,3));
编译app点击
hello world
,日志中看到
Test NAPI 2 + 3 = 5
版权归原作者 Kaninzr 所有, 如有侵权,请联系我们删除。