写在前面的话,作者在入门harmony应用开发后,看到有Native C++工程,那就简单写一个Native C++工程练练手吧,计算器貌似是一个大多数客户端开发入门练手的单机App项目。
- 说一下环境配置吧
- 工具:DevEco Studio NEXT Release;
- HarmonyOS SDK API(工程的compatibleSdkVersion):5.0.0(12);
- 语言:ArkTS,Node-API,C++;
- 运行机器:DevEco Studio自带的模拟器(x86);
- 电脑:Macbook pro;
- 参考:developer.huawei.com/consumer/cn... (开始没注意到,这个文章还是HarmonyOS3.0/4.0的,不过在本项目中也无所谓)
- 开始,先新建一个Native C++工程了,菜鸟操作,直接上图了(直接Next->Finish) 在新建的工程项目中我们下写的代码主要就是三处()
- 1是native侧逻辑,也就是C++代码;
- 2是native侧暴露给ArkTS侧接口的声明,连接native和ArkTS的纽带/桥等等(就是Node-API)
- 3是ArkTS侧逻辑,也就是鸿蒙app页面代码 交代一下新建的工程中有一个简单完整的add方法调用,一个demo示例大家可以照葫芦画瓢
- 从用户操作开始吧,
- ArkTS侧用户页面(也就是截图红框3的Index.ets)用户输入两个数字(number)和一个运算操作(string) 这三个数据给native侧的C++方法,那就先在Index.d.ts文件中声明一下,照着葫芦(案例方法add)画瓢吧。葫芦是两个number参数,返回number。我们要画的瓢是两个number参数和一个string,返回number; 声明:
ts
export const opt: (a: number,o: string, b: number) => number;
- 下面在native侧napi_init.cpp中提供一下opt 引入必要的依赖
arduino
#include "napi/native_api.h"//这个是Native C++中必须要有的Node-API
#include\<cstring> //这个是字符串的比较要用到strcmp
完整C++代码
cpp
#include "napi/native_api.h"
#include <cstring>
static napi_value Opt(napi_env env, napi_callback_info info)
{
size_t argc = 3;
napi_value args[3] = {nullptr};
napi_get_cb_info(env, info, &argc, args , nullptr, nullptr);
napi_valuetype valuetype0;
napi_typeof(env, args[0], &valuetype0);
napi_valuetype valuetype1;
napi_typeof(env, args[1], &valuetype1);
napi_valuetype valuetype2;
napi_typeof(env, args[2], &valuetype2);
double value0;
napi_get_value_double(env, args[0], &value0);
size_t typeLen = 0;
napi_get_value_string_utf8(env, args[1], nullptr, 0, &typeLen);
char *optBuf = new char[typeLen + 1];
napi_get_value_string_utf8(env, args[1], optBuf, typeLen + 1, &typeLen);
double value2;
napi_get_value_double(env, args[2], &value2);
napi_value sum;
if (strcmp(optBuf, "/") == 0) {
napi_create_double(env, value0 / value2, &sum);
} else if (strcmp(optBuf, "+") == 0) {
napi_create_double(env, value0 + value2, &sum);
} else if (strcmp(optBuf, "*") == 0) {
napi_create_double(env, value0 * value2, &sum);
} else if (strcmp(optBuf, "-") == 0) {
napi_create_double(env, value0 - value2, &sum);
}
return sum;
}
EXTERN_C_START
static napi_value Init(napi_env env, napi_value exports)
{
napi_property_descriptor desc[] = {
{ "opt", nullptr, Opt, nullptr, nullptr, nullptr, napi_default, nullptr },
};
napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
return exports;
}
EXTERN_C_END
static napi_module demoModule = {
.nm_version = 1,
.nm_flags = 0,
.nm_filename = nullptr,
.nm_register_func = Init,
.nm_modname = "entry",
.nm_priv = ((void*)0),
.reserved = { 0 },
};
extern "C" __attribute__((constructor)) void RegisterEntryModule(void)
{
napi_module_register(&demoModule);
}
ArkTS侧,先上一个效果图了
这个代码中主要用到Grid()和GridItem(),其中"="按钮用到了GridItem()的rowStart().rowEnd().columnStart().columnEnd(),这里鸿蒙API文档有示例说明。这里多一句,鸿蒙的ArktsUI做了很多,UI效果上原生ArktsUI该有的都有了,还是很强大。
最后,本文只是一个小小的仿写案例,一个记录。像Node-API和Cmake之类,还是可以了解了解,尤其是Cmake,因为我用到是鸿蒙模拟器,很多功能无法使用,具体见官网说明(模拟器与真机的差异)developer.huawei.com/consumer/cn... 同时该设备是x86的,在写导入三方库文件的时候一定要注意这个问题,很多三方提供给鸿蒙的库文件不支持x86。