通过JSI完成JS与c++交互
·
JSI
JSI (JavaScript Interface) 是 OpenHarmony ACELite 框架中的JavaScript 接口层,它提供了 JavaScript 与 C++ 原生代码之间的高效、安全的交互机制。
JSIValue-统一表示所有值的类型
// JSI 抽象值类型
using JSIValue = struct JSIVal *;
// 创建各种类型的值
JSIValue str = JSI::CreateString("Hello");
JSIValue num = JSI::CreateNumber(42);
JSIValue obj = JSI::CreateObject();
JSIValue arr = JSI::CreateArray(5);
基础值创建
// 创建对象
JSIValue obj = JSI::CreateObject();
// 创建字符串
JSIValue str = JSI::CreateString("Hello World");
// 创建数字
JSIValue num = JSI::CreateNumber(42.5);
// 创建布尔值
JSIValue boolVal = JSI::CreateBoolean(true);
// 创建null
JSIValue nullVal = JSI::CreateNull();
// 创建undefined
JSIValue undefinedVal = JSI::CreateUndefined();
// 创建数组
JSIValue arr = JSI::CreateArray(5); // 长度为5的数组
类型检查
// 检查对象类型
JSI::ValueIsObject(value)
// 检查字符串类型
JSI::ValueIsString(value)
// 检查数字类型
JSI::ValueIsNumber(value)
// 检查布尔值类型
JSI::ValueIsBoolean(value)
// 检查null类型
JSI::ValueIsNull(value)
// 检查undefined类型
JSI::ValueIsUndefined(value)
对象操作
设置属性
JSIValue obj = JSI::CreateObject();
// 设置属性
JSI::SetNumberProperty(obj, "age", 25);
JSI::SetStringProperty(obj, "name", "张三");
JSI::SetBooleanProperty(obj, "isStudent", true);
// 嵌套对象
JSIValue address = JSI::CreateObject();
JSI::SetStringProperty(address, "city", "北京");
JSI::SetStringProperty(address, "street", "长安街");
JSI::SetNamedProperty(obj, "address", address);
// 释放对象
JSI::ReleaseValue(address);
获取属性
// 获取数字属性
double age = JSI::GetNumberProperty(obj, "age");
// 获取字符串属性
char* name = JSI::GetStringProperty(obj, "name");
// 使用字符串...
JSI::ReleaseString(name); // 必须释放
// 获取布尔属性
bool isStudent = JSI::GetBooleanProperty(obj, "isStudent");
// 获取对象属性
JSIValue address = JSI::GetNamedProperty(obj, "address");
if (!JSI::ValueIsUndefined(address)) {
char* city = JSI::GetStringProperty(address, "city");
// 使用...
JSI::ReleaseString(city);
JSI::ReleaseValue(address);
}
类型转换
// 宏定义
#define AS_JERRY_VALUE(jsiValue) (jerry_value_t)(uintptr_t) jsiValue
#define AS_JLENGTH_VALUE(jsiValue) (jerry_length_t)(uintptr_t) jsiValue
#define AS_JSI_VALUE(jValue) (JSIValue)(uintptr_t) jValue
// JSI ←→ 引擎值转换
#define AS_JSI_VALUE(jValue) (JSIValue)(uintptr_t) jValue
#define AS_JERRY_VALUE(jsiValue) (jerry_value_t)(uintptr_t) jsiValue
// 使用示例
jerry_value_t jerry_str = jerry_create_string("test");
JSIValue jsi_str = AS_JSI_VALUE(jerry_str); // 引擎 → JSI
jerry_value_t jerry_num = AS_JERRY_VALUE(jsi_num); // JSI → 引擎
模块调用
JS调用C++
// .h文件中声明类和函数
#ifndef OHOS_ACELITE_ROUTER_MODULE_H
#define OHOS_ACELITE_ROUTER_MODULE_H
#include "jsi.h"
#include "non_copyable.h"
namespace OHOS {
namespace ACELite {
/**
* @brief: The module of router
*/
class RouterModule final : public MemoryHeap {
public:
ACE_DISALLOW_COPY_AND_MOVE(RouterModule);
RouterModule() {}
~RouterModule() {}
static JSIValue Replace(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum);
};
void InitRouterModule(JSIValue exports);
} // namespace ACELite
} // namespace OHOS
#endif // OHOS_ACELITE_ROUTER_MODULE_H
.cpp
#include "router_module.h"
#include "ace_log.h"
#include "js_ability_impl.h"
#include "js_app_context.h"
#include "js_profiler.h"
#include "jsi/internal/jsi_internal.h"
namespace OHOS {
namespace ACELite {
void InitRouterModule(JSIValue exports)
{
// SetModuleAPI将RouterModule::Replace函数指向replace
JSI::SetModuleAPI(exports, "replace", RouterModule::Replace);
}
JSIValue RouterModule::Replace(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum)
{
// 参数判断
if (argsNum != 1 || args == nullptr) {
HILOG_ERROR(HILOG_MODULE_ACE, "Replace args invalid, args num(%{public}d).", argsNum);
return AS_JSI_VALUE(jerry_create_error(JERRY_ERROR_TYPE,
reinterpret_cast<const jerry_char_t *>("params should only be one object.")));
}
// 获取第一个参数对象
jerry_value_t object = AS_JERRY_VALUE(args[0]);
// 获取应用上下文
JsAppContext* appContext = JsAppContext::GetInstance();
const JSAbilityImpl* topJsAbilityImpl = appContext->GetTopJSAbilityImpl();
if (topJsAbilityImpl == nullptr) {
HILOG_ERROR(HILOG_MODULE_ACE, "topJsAbilityImpl is null.");
return AS_JSI_VALUE(UNDEFINED);
}
// 获取路由实例
Router* router = const_cast<Router *>(topJsAbilityImpl->GetRouter());
if (router == nullptr) {
HILOG_ERROR(HILOG_MODULE_ACE, "router is null.");
return AS_JSI_VALUE(UNDEFINED);
}
// 调用 router 的 Replace 方法执行实际的路由跳转
jerry_value_t replaceResult = router->Replace(object);
return AS_JSI_VALUE(replaceResult);
}
} // namespace ACELite
} // namespace OHOS
最后在ohos_module_config.h文件中注册模块
js调用
// 页面跳转. router.replace(uri: 'About', params: (id: '1')))
router.replace({
url: 'pages/About/index',
params: {
id: '1',
name: 'test'
}
});
C++调用JS函数
GetNamedProperty提取JS对象属性,调用JS函数CallFunction
// 测试 testStandardCallback 函数 - 标准成功/失败回调
console.log('Testing testStandardCallback...');
testStandardCallback(
success: function() {
console.log('Success callback called! Operation completed successfully.');
},
fail: function() {
console.log('Fail callback called! Operation failed.');
},
complete: function() {
console.log('Complete callback called! Operation finished (success or fail).');
}
});
JSIValue SampleModule::TestStandardCallback(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
{
JSIValue undefValue = JSI::CreateUndefined();
if ((args == nullptr) || (argsNum == 0) || JSI::ValueIsUndefined(args[0])) {
return undefValue;
}
// 获取成功失败函数
JSIValue success = JSI::GetNamedProperty(args[0], CB_SUCCESS);
JSIValue fail = JSI::GetNamedProperty(args[0], CB_FAIL);
JSIValue complete = JSI::GetNamedProperty(args[0], CB_COMPLETE);
// 调用函数
JSI::CallFunction(success, thisVal, nullptr, 0);
JSI::CallFunction(complete, thisVal, nullptr, 0);
JSI::ReleaseValueList(success, fail, complete);
return undefValue;
}
更多推荐
所有评论(0)