HarmonyOS aki不支持绑定返回值为智能指针、无符号整数、无符号字符的函数,napi如何处理智能指针、无符号整数、无符号字符并暴露给ArkTS使用?

1、aki无法绑定std::shared\_ptr(智能指针),后续是否会支持智能指针和更多其他返回值的的函数,比如无符号整数unsigned int,无符号字符unsigned char,该如何处理此类情况?

2、aki目前无法处理智能指针、无符号整数、无符号字符,不用aki用napi如何处理智能指针、无符号整数、无符号字符并暴露给ArkTS使用,希望能提供demo。

阅读 548
1 个回答

智能指针这种场景,请参考DEMO:

src/main/ets/pages/Index.ets文件:

import { hilog } from '@kit.PerformanceAnalysisKit';
import testNapi from 'libentry.so';
let manager = new testNapi.TestObject();
manager.Register(1, "xxx")
manager.Register(2, "xxx")
manager.Register(3, "xxx")
manager.Register(4, "xxx")
hilog.info(0x0000, 'testTag', 'IsExist(2):%{public}s', manager.IsExist(2));
hilog.info(0x0000, 'testTag', 'GetNameById(4):%{public}s', manager.GetNameById(4));
manager.UnRegister(3);
hilog.info(0x0000, 'testTag', 'IsExist(3):%{public}s', manager.IsExist(3));
manager.SetAgeById(4, 66)
hilog.info(0x0000, 'testTag', 'SetAgeById(4, 66) age:%{public}d', manager.GetAgeById(4));
let personObj = manager.GetPersonById(4) as testNapi.PersonObject;
if (personObj != null) {
  hilog.info(0x0000, 'testTag', 'id:%{public}d, age:%{public}d, name:%{public}s', personObj.id_, personObj.age_, personObj.name_);
}
personObj = manager.GetPersonById(3) as testNapi.PersonObject;
if (personObj != null) {
  hilog.info(0x0000, 'testTag', 'id:%{public}d, age:%{public}d, name:%{public}s', personObj.id_, personObj.age_, personObj.name_);
} else {
  hilog.info(0x0000, 'testTag', 'manager.GetPersonById(3) failed.');
}
let obj = testNapi.TestObject.ReturnOject();
hilog.info(0x0000, 'testTag', 'obj.sum_:%{public}d', obj.sum_);

@Entry
@Component
struct Index {
  @State message: string = 'Hello World';
  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
          .onClick(() => {
            let obj1 = new testNapi.TestObject();
            let obj2 = new testNapi.TestObject(10);
            let result = obj2.MultiplyObject(obj1, obj2);
            hilog.info(0x0000, 'testTag', 'result:%{public}d', result);
            hilog.info(0x0000, 'testTag', 'sum_:%{public}d', obj2.sum_);
            hilog.info(0x0000, 'testTag', 'constant value:%{public}d', testNapi.TestObject.GetSConstValue());
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}

src/main/cpp/CMakeLists.txt文件:

# the minimum version of CMake.
cmake_minimum_required(VERSION 3.5.0)
project(aki)
set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})
if(DEFINED PACKAGE_FIND_FILE)
include(${PACKAGE_FIND_FILE})
endif()
include_directories(${NATIVERENDER_ROOT_PATH}
${NATIVERENDER_ROOT_PATH}/include)
set(AKI_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules/@ohos/aki) # 设置AKI根路径
set(CMAKE_MODULE_PATH ${AKI_ROOT_PATH})
find_package(Aki REQUIRED)
add_library(entry SHARED napi_init.cpp)
target_link_libraries(entry PUBLIC libace_napi.z.so Aki::libjsbind)

src/main/cpp/napi\_init.cpp文件:

#include <string>
#include <aki/jsbind.h>
#include <vector>
#define LOG_TAG "testTag"
#include "hilog/log.h"

using namespace std;

class PersonObject {
  public:
    PersonObject(string name) {
  this->name_ = name;
  this->age_ = 10;
}
~PersonObject() {
  OH_LOG_INFO(LOG_APP, "~PersonObject, id:%{public}d, age:%{public}d, name:%{public}s", this->id_, this->age_,
    this->name_.c_str());
}

void SetId(unsigned short id) {
  this->id_ = id;
}

unsigned short GetId() {
  return this->id_;
}

string GetName() {
  return this->name_;
}

void SetAge(unsigned char age) {
  this->age_ = age;
}

unsigned char GetAge() {
  return this->age_;
}
private:
  unsigned short id_;
std::string name_;
unsigned char age_;
};

class TestObject {
  public:
    TestObject() {
  this->value_ = 5;
}

TestObject(double value) {
  this->value_ = value;
}

~TestObject() {
  OH_LOG_INFO(LOG_APP, "~TestObject, sum_:%{public}f, uValue_:%{public}d, cValue_:%{public}d", this->sum_, this->uValue_,
    this->cValue_);
}

double MultiplyObject(TestObject obj1, TestObject obj2) {
  return obj1.value_ * obj2.value_;
}

static TestObject ReturnOject() {
  TestObject obj;
  obj.sum_ = 999;

  return obj;
}

static double GetSConstValue() {
  return 10.05;
}

double Multiply(double mult) {
  value_ *= mult;
  return value_;
}

void Register(unsigned short id, string name) {
  shared_ptr<PersonObject> personOjb(new PersonObject(name));
  personOjb->SetId(id);
  personMan_.push_back(personOjb);
}

void UnRegister(unsigned short id) {
  for (int i = 0; i < personMan_.size(); i++) {
    if (personMan_[i]->GetId() == id) {
      personMan_.erase(personMan_.begin() + i);
      return;
    }
  }
}

bool IsExist(unsigned short id) {
  for (int i = 0; i < personMan_.size(); i++) {
    if (personMan_[i]->GetId() == id) {
      return true;
    }
  }
  return false;
}

string GetNameById(unsigned short id) {
  for (int i = 0; i < personMan_.size(); i++) {
    if (personMan_[i]->GetId() == id) {
      return personMan_[i]->GetName();
    }
  }
  return "";
}

void SetAgeById(unsigned short id, unsigned char age) {
  for (int i = 0; i < personMan_.size(); i++) {
    if (personMan_[i]->GetId() == id) {
      personMan_[i]->SetAge(age);
      return;
    }
  }
}

unsigned char GetAgeById(unsigned short id) {
  OH_LOG_INFO(LOG_APP, "enter GetAgeById");
  for (int i = 0; i < personMan_.size(); i++) {
    if (personMan_[i]->GetId() == id) {
      return personMan_[i]->GetAge();
    }
  }
  return 0;
}

napi_value GetPersonById(unsigned short id) {
  #if JSBIND_USING_NAPI
    napi_env env = aki::JSBind::GetScopedEnv();
  napi_value personOjb;
  napi_create_object(env, &personOjb);

  for (int i = 0; i < personMan_.size(); i++) {
    if (personMan_[i]->GetId() == id) {
      napi_value personId;
      napi_create_int32(env, personMan_[i]->GetId(), &personId);
      napi_set_named_property(env, personOjb, "id_", personId);

      napi_value personAge;
      napi_create_int32(env, personMan_[i]->GetAge(), &personAge);
      napi_set_named_property(env, personOjb, "age_", personAge);

      napi_value personName;
      napi_create_string_utf8(env, personMan_[i]->GetName().c_str(), strlen(personMan_[i]->GetName().c_str()),&personName);
      napi_set_named_property(env, personOjb, "name_", personName);

      return personOjb;
    }
  }
  #endif
  return nullptr;
}

public:
  double sum_ = 20;
unsigned int uValue_ = 90;
unsigned char cValue_ = 30;

private:
  double value_;
vector<shared_ptr<PersonObject>> personMan_;
};

JSBIND_CLASS(TestObject) {
  JSBIND_CONSTRUCTOR<>();
  JSBIND_CONSTRUCTOR<double>();
  JSBIND_METHOD(GetSConstValue);
  JSBIND_METHOD(MultiplyObject);
  JSBIND_METHOD(Multiply);
  JSBIND_METHOD(Register);
  JSBIND_METHOD(UnRegister);
  JSBIND_METHOD(IsExist);
  JSBIND_METHOD(GetNameById);
  JSBIND_METHOD(SetAgeById);
  JSBIND_METHOD(GetAgeById);
  JSBIND_METHOD(GetPersonById);
  JSBIND_METHOD(ReturnOject);
  JSBIND_PROPERTY(sum_);
  JSBIND_PROPERTY(uValue_);
  JSBIND_PROPERTY(cValue_);
}
JSBIND_ADDON(entry);

src/main/cpp/types/libentry/Index.d.ts文件:

declare class PersonObject {
  id_: number;
  name_: string;
  age_: number;
}

export class TestObject {
  constructor();
  constructor(value: number);
  MultiplyObject(obj1: TestObject, obj2: TestObject): number;
  Multiply(mult: number): number;
  static GetSConstValue(): number;
  Register(id: number, name: string): void;
  UnRegister(id: number): void;
  IsExist(id: number): boolean;
  GetNameById(id: number): string;
  SetAgeById(id: number, age: number): void;
  GetAgeById(id: number): number;
  GetPersonById(id: number): object;
  static ReturnOject(): TestObject;
  public sum_: number;
  public uValue_: number;
  public cValue_: number;
}