想了解更多关于开源的内容,请访问:51CTO 开源基础软件社区https://ost.51cto.com#ifndef __NAPI_TEST_H__
#define __NAPI_TEST_H__
#include "napi/native_api.h"
#include <js_native_api_types.h>
#include <iostream>
#define NAPI_CLASS_NAME "NapiTestClass"
class NapiTest {
public:
NapiTest() : mEnv(nullptr), mRef(nullptr) {
}
NapiTest(napi_env env) : mEnv(env), mRef(nullptr){
}
~NapiTest();
// 创建NapiTest类的实体,并将实体返回到应用端,该方法为js创建一个类实体,因此需要将该接口对外导出
static napi_value Create(napi_env env, napi_callback_info info);
// 初始化js类并设置对应属性并将其导出
static napi_value Init(napi_env env, napi_value exports);
private:
// 设置数据,此方法给到js直接调用,因此需要将该接口对外导出
static napi_value SetMsg(napi_env env, napi_callback_info info);
// 获取数据,此方法给到js直接调用,因此需要将该接口对外导出
static napi_value GetMsg(napi_env env, napi_callback_info info);
// 定义js结构体时实际的构建函数
static napi_value Constructor(napi_env env, napi_callback_info info);
// 释放资源的函数(类似类的析构函数)
static void Destructor(napi_env env, void *nativeObject, void *finalize);
// 生命周期变量
static napi_ref sConstructor_;
// 设置和获取数据的变量
static std::string _msg;
// 记录环境变量
napi_env mEnv = nullptr;
// 记录生命周期变量
napi_ref mRef = nullptr;
};
#endif /* __NAPI_TEST_H__ */// 在定义js类之前,需要先设置类对外导出的方法
napi_property_descriptor desc[] = {
{ "getMsg", nullptr, NapiTest::GetMsg, nullptr, nullptr, nullptr, napi_default, nullptr },
{ "setMsg", nullptr, NapiTest::SetMsg, nullptr, nullptr, nullptr, napi_default, nullptr },
{ "create", nullptr, NapiTest::Create, nullptr, nullptr, nullptr, napi_default, nullptr }
};typedef struct {
// utf8name和name其中一个必须是NULL
const char* utf8name;
napi_value name;
napi_callback method;
napi_callback getter;
napi_callback setter;
napi_value value;
napi_property_attributes attributes;
void* data;
} napi_property_descriptor;napi_value constructor = nullptr;
// 定义与C++类相对应的JavaScript类
if (napi_define_class(env, NAPI_CLASS_NAME, NAPI_AUTO_LENGTH, Constructor, nullptr, sizeof(desc) / sizeof(desc[0]),
desc, &constructor) != napi_ok) {
// "!="用来检查两个操作数的值是否相等,如果不相等则条件为真
return nullptr;
}napi_status napi_define_class(napi_env env,
const char* utf8name,
size_t length,
napi_callback constructor,
void* data,
size_t property_count,
const napi_property_descriptor* properties,
napi_value* result);JS构造函数。
如果一个js函数被使用new操作符来调用了,那么这个函数就称之为js构造函数C++类回调函数我们调用别人的API叫call,调用的第三方API调用我们的函数叫回调(callback)

napi_value NapiTest::Constructor(napi_env env, napi_callback_info info)
{
napi_value undefineVar = nullptr, thisVar = nullptr;
napi_get_undefined(env, &undefineVar);
// 获取传入的参数对象,对象不为空,根据该参数创建实例并并绑定到该对象
if (napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr) == napi_ok && thisVar != nullptr) {
// 创建NapiTest 实例
NapiTest *reference = new NapiTest(env);
// 绑定实例到对象并获取对象的生命周期
if (napi_wrap(env, thisVar, reinterpret_cast<void *>(reference), NapiTest::Destructor, nullptr, &(reference->mRef)) == napi_ok) {
return thisVar;
}
return thisVar;
}
return undefineVar;
}
void NapiTest::Destructor(napi_env env, void *nativeObject, void *finalize)
{
// 释放资源
NapiTest *test = reinterpret_cast<NapiTest*>(nativeObject);
test->~NapiTest();
}void NapiTest::Destructor(napi_env env, void *nativeObject, void *finalize)
{
// 类析构函数,释放资源
NapiTest *test = reinterpret_cast<NapiTest*>(nativeObject);
test->~NapiTest();
}napi_status napi_wrap(napi_env env,
napi_value js_object,
void* native_object,
napi_finalize finalize_cb,
void* finalize_hint,
napi_ref* result);napi_status napi_get_cb_info(napi_env env,
napi_callback_info cbinfo,
size_t* argc,
napi_value* argv,
napi_value* this_arg,
void** data)// 创建生命周期,初始引用计数设为1
if (napi_create_reference(env, constructor, 1, &sConstructor_) != napi_ok) {
return nullptr;
}
// 设置NapiTest对象相关属性并绑定到导出变量exports
if (napi_set_named_property(env, exports, NAPI_CLASS_NAME, constructor) != napi_ok) {
return nullptr;
}if (napi_create_reference(env, constructor , 1, &sConstructor_) != napi_ok) {
return nullptr;
}NAPI_EXTERN napi_status napi_create_reference(napi_env env,
napi_value value,
uint32_t initial_refcount,
napi_ref* result);// 设置constructor对象相关属性并绑定到导出变量exports
if (napi_set_named_property(env, exports, NAPI_CLASS_NAME, constructor) != napi_ok) {
return nullptr;
}napi_status napi_set_named_property(napi_env env,
napi_value object,
const char* utf8Name,
napi_value value);napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);napi_status napi_define_properties(napi_env env,
napi_value object,
size_t property_count,
const napi_property_descriptor* properties);napi_value NapiTest::Create(napi_env env, napi_callback_info info) {
napi_status status;
napi_value constructor = nullptr, result = nullptr;
// 获取生命周期变量
status = napi_get_reference_value(env, sConstructor_, &constructor);
// 创建生命周期内的实例对象并将其返回
status = napi_new_instance(env, constructor, 0, nullptr, &result);
auto napiTest = new NapiTest();
// 绑定实例类创建NapiTest到导出的对象result
if (napi_wrap(env, result, reinterpret_cast<void *>(napiTest), Destructor,
nullptr, &(napiTest->mRef)) == napi_ok) {
return result;
}
return nullptr;
}NAPI_EXTERN napi_status napi_get_reference_value(napi_env env,
napi_ref ref,
napi_value* result);napi_status napi_new_instance(napi_env env,
napi_value cons,
size_t argc,
napi_value* argv,
napi_value* result)使用NAPI框架代码生成工具,可以根据.h生成.d.ts
https://gitee.com/openharmony/napi_generator/blob/master/docs/INSTRUCTION_ZH.md。
export const create : () => NapiTest;
export class NapiTest {
setMsg(msg: string): void;
getMsg(): string;
}export class NapiTest {
create();
setMsg(msg: string): void;
getMsg(): string;
}# the minimum version of CMake.
cmake_minimum_required(VERSION 3.4.1)
project(ObjectWrapTest)
set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})
# 头文件路径
include_directories(${NATIVERENDER_ROOT_PATH}
${NATIVERENDER_ROOT_PATH}/include)
# 动态库源文件
add_library(entry SHARED hello.cpp NapiTest.cpp)
# 依赖libace_napi.z.so动态库
target_link_libraries(entry PUBLIC libace_napi.z.so )// 让IDE不检查文件语法
// @ts-nocheck
import testNapi from "libentry.so";
@Entry
@Component
struct Index {
@State message: string = '导出对象'
@State nativePointer:number = 0
// 创建对象tt
tt = testNapi.create();
build() {
Row() {
Column() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
.onClick(() => {
console.info("[NapiTest] Test NAPI 2 + 3 = " + testNapi.add(2, 3));
try{
if (this.nativePointer == 0) {
// log打印,在程序中添加 log
console.info("[NapiTest] Test NAPI add(2, 3) 1");
this.nativePointer = testNapi.add(2, 3)
console.info("[NapiTest] Test NAPI add(2, 3) 2");
this.tt.setMsg("2+3")
console.info("[NapiTest] Test NAPI add(2, 3) 3");
} else {
console.info("[NapiTest] Test NAPI add(0, 0) 1");
this.nativePointer = testNapi.add(0, 0)
console.info("[NapiTest] Test NAPI add(0, 0) 2");
this.tt.setMsg("4+5")
console.info("[NapiTest] Test NAPI add(0, 0) 3");
}
} catch(e) {
console.info("[NapiTest]Test NAPI error" + JSON.stringify(e));
}
console.info("[NapiTest]Test NAPI " + this.tt.getMsg() + " = " + this.nativePointer);
})
}
.width('100%')
}
.height('100%')
}
}总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
我正在使用i18n从头开始构建一个多语言网络应用程序,虽然我自己可以处理一大堆yml文件,但我说的语言(非常)有限,最终我想寻求外部帮助帮助。我想知道这里是否有人在使用UI插件/gem(与django上的django-rosetta不同)来处理多个翻译器,其中一些翻译器不愿意或无法处理存储库中的100多个文件,处理语言数据。谢谢&问候,安德拉斯(如果您已经在rubyonrails-talk上遇到了这个问题,我们深表歉意) 最佳答案 有一个rails3branchofthetolkgem在github上。您可以通过在Gemfi
在控制台中反复尝试之后,我想到了这种方法,可以按发生日期对类似activerecord的(Mongoid)对象进行分组。我不确定这是完成此任务的最佳方法,但它确实有效。有没有人有更好的建议,或者这是一个很好的方法?#eventsisanarrayofactiverecord-likeobjectsthatincludeatimeattributeevents.map{|event|#converteventsarrayintoanarrayofhasheswiththedayofthemonthandtheevent{:number=>event.time.day,:event=>ev
我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss
好的,所以我的目标是轻松地将一些数据保存到磁盘以备后用。您如何简单地写入然后读取一个对象?所以如果我有一个简单的类classCattr_accessor:a,:bdefinitialize(a,b)@a,@b=a,bendend所以如果我从中非常快地制作一个objobj=C.new("foo","bar")#justgaveitsomerandomvalues然后我可以把它变成一个kindaidstring=obj.to_s#whichreturns""我终于可以将此字符串打印到文件或其他内容中。我的问题是,我该如何再次将这个id变回一个对象?我知道我可以自己挑选信息并制作一个接受该信
如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象
我在Rails工作并有以下类(class):classPlayer当我运行时bundleexecrailsconsole然后尝试:a=Player.new("me",5.0,"UCLA")我回来了:=>#我不知道为什么Player对象不会在这里初始化。关于可能导致此问题的操作/解释的任何建议?谢谢,马里奥格 最佳答案 havenoideawhythePlayerobjectwouldn'tbeinitializedhere它没有初始化很简单,因为你还没有初始化它!您已经覆盖了ActiveRecord::Base初始化方法,但您没有调
我有一个服务模型/表及其注册表。在表单中,我几乎拥有服务的所有字段,但我想在验证服务对象之前自动设置其中一些值。示例:--服务Controller#创建Action:defcreate@service=Service.new@service_form=ServiceFormObject.new(@service)@service_form.validate(params[:service_form_object])and@service_form.saverespond_with(@service_form,location:admin_services_path)end在验证@ser
我安装了ruby版本管理器,并将RVM安装的ruby实现设置为默认值,这样'哪个ruby'显示'~/.rvm/ruby-1.8.6-p383/bin/ruby'但是当我在emacs中打开inf-ruby缓冲区时,它使用安装在/usr/bin中的ruby。有没有办法让emacs像shell一样尊重ruby的路径?谢谢! 最佳答案 我创建了一个emacs扩展来将rvm集成到emacs中。如果您有兴趣,可以在这里获取:http://github.com/senny/rvm.el
我想让一个yaml对象引用另一个,如下所示:intro:"Hello,dearuser."registration:$introThanksforregistering!new_message:$introYouhaveanewmessage!上面的语法只是它如何工作的一个例子(这也是它在thiscpanmodule中的工作方式。)我正在使用标准的rubyyaml解析器。这可能吗? 最佳答案 一些yaml对象确实引用了其他对象:irb>require'yaml'#=>trueirb>str="hello"#=>"hello"ir