OpenHarmony 汉字转拼音

发布时间 2023-05-31 15:50:36作者: JoshuaGeng
 
开发前准备:
 
 
API:8
基于Native C++ 模版,开发 ets调用C++

开发步骤:

新建工程:
便于测试方便使用的是Harmony OS 项目,Open Harmony OS 没模拟器,不方便调试
最终结果都是一样的
 
选择Native C++ 之后Next 点完成
 
新建项目多了CPP模块如下:
这个里面已经帮忙写好了一个例子,如何使用ets调用c++
 
启动一个远程模拟器运行下最终效果
 

开发实现:

 

代码结构:

文件的结构如下
├── cpp:C++代码区
├── cpp:C++代码区
│   ├── types:                                           // 接口存放文件夹 
│   │   └── libhello
│   │       ├── index.d.ts                            // 接口文件 
│   │       └── package.json                         // 接口注册配置文件 
│   ├── CmakeList.text                               // Cmake打包配置文件 
│   └── hello.cpp                                    // C++源代码 
└── ets                                                // ets代码区 
    └── MainAbility 
        └── pages                                           
                        └── index.ets                        // 主页面        
 
 
 

eTS调用C++方法流程

1、应用架构。 整个应用架构可以分为三部分:C++侧、eTS侧、工具链。
  • C++侧:包含各种文件的引用、C++或者C代码、Node_API将C++函数与JavaScript关联的信息等。
  • eTS侧:包含界面UI、自身方法,调用引用包的方法等。
  • 工具链:包含Cmake打包工具在内的系列工具。 在eTS调用C++方法的过程中,需要使用到Node_API、Cmake等工具来做中间转换,整个架构及其关联关系如下:
 
在上面的示意图中,hello.cpp文件用来编写C++代码,并通过Node_API将C++函数与JavaScript方法关联。C++代码通过Cmake打包工具打包成动态链接库SO文件,并通过xxx.d.ts文件对外提供接口。eTS端通过引入SO包的方式去调用SO文件中的接口。
 
2、调用、打包流程。 在eTS调用C++方法的过程中,调用、打包流程如下:
上图中C++代码通过Cmake打包成SO文件后可以直接被eTS侧引入,最终通过hivgor一起打包成可执行的HarmonyOS hap包。
 
重点环节说明如下:
  • ①cpp源码编写,Node_API将C++函数与JavaScript方法关联,index.d.ts接口文档,package.json文件编写。
  • (1)c++编写"hyPotC"方法,用以实现计算两个数平方和的平方根。
#include "napi/native_api.h" 
#include "math.h" 
static napi_value hyPotC(napi_env env, napi_callback_info info){ 
    ... 
}
(2)Node_API将C++函数与JavaScript方法关联。 将C++的"hyPotC"函数进行注册,注册的对外接口名为"hyPot"。
static napi_value Init(napi_env env, napi_value exports){ 
    napi_property_descriptor desc[] = { 
        { "hyPot", nullptr, hyPotC, nullptr, nullptr, nullptr, napi_default, nullptr }, 
    }; 
   ... 
}
(3)index.d.ts接口文档编写。
export const hyPot: (a: number, b: number) => number;
 
(4)package.json文件编写。
{ 
  "name": "libhello.so", 
  "types": "./index.d.ts" 
}
Cmake打包配置、CmakeList.txt配置需要添加的hello.cpp文件。
add_library(hello SHARED hello.cpp
 
index.ets中引入SO包,调用SO包中的hyPot方法。
import libHello from "libhello.so" 
... 
  Button(this.buttonSubmit) 
  ... 
  .onClick(() => { 
    this.result = libHello.hyPot(this.num1,this.num2) 
  })
 
 

C++方法实现:

方法传入参数说明:
     
参数名 类型 说明
env napi_env 用于表示底层 Node-API 实现可以用来保持 VM 特定状态的上下文。
info napi_callback_info 传递给回调函数的不透明数据类型。它可用于获取有关调用回调的上下文的附加信息。
napi_value   这是一个不透明的指针,用于表示 JavaScript 值(这里返回的是计算后的结果)。
 
参考说明:
#include "napi/native_api.h" 
#include "math.h" 
static napi_value hyPotC(napi_env env, napi_callback_info info) 
{ 
    // 参数数量 
    size_t argc = 2; 
    // 声明参数数组 
    napi_value args[2] = {nullptr}; 
    // 获取传入的参数并依次放入参数数组中 
    napi_get_cb_info(env, info, &argc, args , nullptr, nullptr); 
    // 对第一个js参数类型进行判定 
    napi_valuetype valueType0; 
    napi_typeof(env, args[0], &valueType0); 
    // 对第二个js参数类型进行判定 
    napi_valuetype valueType1; 
    napi_typeof(env, args[1], &valueType1); 
    // 将第一个传入参数转化为double类型 
    double value0; 
    napi_get_value_double(env, args[0], &value0); 
    // 将第二个传入参数转化为double类型 
    double value1; 
    napi_get_value_double(env, args[1], &value1); 
    // 声明返回结果字段,并调用C标准库的hypot方法进行计算 
    napi_value sum; 
    double result = hypot(value0,value1); 
    napi_create_double(env, result, &sum); 
    return sum; 
    }
注册模块。
模块注册是固定写法,在napi_property_descriptor desc[]中我们需要将编写的"hanziToPinyin"方法(从左至右第三个参数)与对暴露的接口"hanziToPinyin"接口(从左至右第一个参数)进行关联,其他参考示例默认填写即可。 示例:
EXTERN_C_START
static napi_value Init(napi_env env, napi_value exports) {
    napi_property_descriptor desc[] = {
        {"add", nullptr, Add, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"hanziToPinyin", nullptr, HanziToPinyin, nullptr, nullptr, nullptr, napi_default, nullptr}};

    napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
    return exports;
}
EXTERN_C_END
 
编写接口文档。 index.d.ts用于对外提供方法、说明文档(名字可以更改,点击方法可以直接链接到index.d.ts)。
export const hanziToPinyin: (text: string) => string;
package.json文件中将index.d.ts与cpp文件关联起来。
{
  "name": "libpinyin.so",
  "types": "./index.d.ts"
}
CMakeLists.txt配置CMake打包参数。 CMakeLists.txt是CMake打包的配置文件,里面的大部分内容无需修改,project、add_library方法中的内容可以根据实际情况修改。
CMakeLists.txt
# the minimum version of CMake.
cmake_minimum_required(VERSION 3.4.1)
project(ChineseToPinyin)
set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})

include_directories(${NATIVERENDER_ROOT_PATH}
                    ${NATIVERENDER_ROOT_PATH}/include)

add_library(pinyin SHARED pinyin_napi.cpp pinyin_helper.cpp pinyin_data.cpp)

# hilog_ndk.z libhilog_ndk.z.so
#target_link_libraries(chess PUBLIC hilog_ndk.z.so libace_napi.z.so libc++.a)

target_link_libraries(pinyin PUBLIC hilog_ndk.z.so libace_napi.z.so libc++.a)
#target_link_libraries(${project_name} hilog_ndk.z)
libace_napi.z.so napi 库
libc++.a c++库
 
// 汉字转拼音的工具类
#include "pinyin_helper.h"
 
// 汉字拼音的数据集合 #include "pinyin_data.h"
 
项目地址: