当前位置:   article > 正文

用Rust开发鸿蒙应用(ArkTS NAPI)_鸿蒙 rust

鸿蒙 rust

开发流程

在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",
    }
  ]
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

创建rust项目

cargo new hello
  • 1

修改 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"

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

lib.rs 添加测试代码

use std::ffi::{CString};
use std::ptr::{null_mut};
use oh_napi_sys::*;
use ctor::ctor;

extern "C" fn add(env: napi_env, info: napi_callback_info) ->napi_value{
    // 期望从ArkTS侧获取的参数的数量,napi_value可理解为ArkTS value在Native方法中的表现形式。

    let mut args:[napi_value; 2] = [null_mut();2];
    let mut argc = args.len();
    unsafe {
        napi_get_cb_info(env, info, &mut argc, args.as_mut_ptr(), null_mut(), null_mut());

        let mut valuetype0  = napi_valuetype_napi_undefined;
        napi_typeof(env, args[0], &mut valuetype0);
        let mut valuetype1  = napi_valuetype_napi_undefined;
        napi_typeof(env, args[1], &mut valuetype1);

        if (valuetype0 != napi_valuetype_napi_number) || (valuetype1 != napi_valuetype_napi_number) {
            let mut undefined: napi_value= null_mut();
            napi_get_undefined(env, &mut undefined);
            return undefined;
        }


        // 将获取的ArkTS参数转换为Native信息,此处ArkTS侧传入了两个number,这里将其转换为Native侧可以操作的double类型。
        let mut value0 = 0f64;
        napi_get_value_double(env, args[0], &mut value0);

        let mut value1 = 0f64;
        napi_get_value_double(env, args[1], &mut value1);

        // Native侧的业务逻辑,这里简单以两数相加为例。
        let native_sum = value0 + value1;


        // 此处将Native侧业务逻辑处理结果转换为ArkTS值,并返回给ArkTS。
        let mut sum = null_mut();
        napi_create_double(env, native_sum, &mut sum);

        return sum;
    }
}
type Callback = extern "C" fn(env: napi_env, info: napi_callback_info) -> napi_value;

unsafe fn new_func_descriptor(name: &'static str, 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]
fn register_hello_module(){
    let name= CString::new( "hello").unwrap();

    let mut 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: 0 as * mut _,
        reserved: [0 as * mut _;4],
    };


    unsafe {
        napi_module_register(&mut hello_module);
    }

    // Init将在exports上挂上Add/NativeCallArkTS这些Native方法,此处的exports就是开发者import之后获取到的ArkTS对象。
    unsafe extern "C" fn init(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;
    }
}


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93

添加对应ts代码

// entry/src/main/rust/types/libhello/index.d.ts

export const add: (a: number, b: number) => number;
  • 1
  • 2
  • 3
// entry/src/main/rust/types/libhello/oh-package.json5

{
  "name": "libhello.so",
  "types": "./index.d.ts",
  "version": "",
  "description": "Please describe the basic information."
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

配置依赖

// 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"
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

在 rust 根目录下编译,添加ohos目标的教程可以参考 Rust交叉编译OpenHarmony应用动态库

cargo build -Zbuild-std  --release  --target aarch64-unknown-linux-ohos
  • 1

将编译好的 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));
  • 1
  • 2
  • 3
  • 4

编译app点击hello world,日志中看到 Test NAPI 2 + 3 = 5

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/263871
推荐阅读
相关标签
  

闽ICP备14008679号