DEV Community

Cover image for [Daily HarmonyOS Next Knowledge] Multiple har Dependencies, Specifying Compilation Architecture, Mutual
kouwei qing
kouwei qing

Posted on

[Daily HarmonyOS Next Knowledge] Multiple har Dependencies, Specifying Compilation Architecture, Mutual

[Daily HarmonyOS Next Knowledge] Multiple har Dependencies, Specifying Compilation Architecture, Mutual Calls Between ArkTS and C++

1. Issues with Multiple har Dependencies

If harA depends on harB and harC, and harB depends on harC, how to build such dependency relationships?

  1. Both direct and indirect dependencies are hosted on a remote repository, relying on version numbers.
  2. If not hosted on a remote repository, it is recommended to place both direct and indirect har packages into the project and use overrides to point to the local har package paths.
  3. If sub-dependencies are local har dependencies, they need to be placed in the direct dependency module for building .har packages for other projects. For example, if A depends on B.har and B.har depends on C.har, C.har must be included in module B during the construction of B.har.

2. How to Specify or Determine the Current Compilation Architecture?

Specify the compilation architecture:

  1. Add abiFilters configuration in the build-profile.json5 file:
"externalNativeOptions": {
  "path": "./src/main/cpp/CMakeLists.txt",
  "arguments": "",
  "cppFlags": "",
  "abiFilters": [
    "arm64-v8a"
  ]
}
Enter fullscreen mode Exit fullscreen mode
  1. Add compilation parameters in the arguments of build-profile.json5 or via the command line:
-DOHOS_ARCH=armeabi-v7a
Enter fullscreen mode Exit fullscreen mode

Determine the compilation architecture:

The OHOS_ARCH macro in CMakeList.txt represents the current compilation architecture:

if (${OHOS_ARCH} STREQUAL "armeabi-v7a")
message('armeabi-v7a')
elseif (${OHOS_ARCH} STREQUAL "arm64-v8a")
message('arm64-v8a')
else()
message("unkonow")
endif()
Enter fullscreen mode Exit fullscreen mode

3. When starting debugging or running an application/service, an error occurs during HAP installation, prompting "error: install failed due to grant request permissions failed".

The default app level is normal, which can only use normal-level permissions. Using system_basic or system_core-level permissions will cause an error.

Modify the APL level in the UnsgnedDebugProfileTemplate.json file to system_basic or system_core, then re-sign and package.

4. How to Achieve Object Passing Between ArkTS and C/C++?

ArkTS calls C/C++:

  1. ArkTS class objects are passed to the NAPI side.
  2. NAPI retrieves and outputs object properties.
  3. NAPI calls object methods.
// Animals class
class Animals {
  name: string
  age: number

  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }

  add(a: number, b: number): number {
    return a + b;
  }
}
Enter fullscreen mode Exit fullscreen mode
// Passing objects in ArkTS
Button("TestObject")
  .onClick(() => {
    let ani: Animals = new Animals('Bob', 5)
    testNapi.TestObject(ani)
  })
Enter fullscreen mode Exit fullscreen mode
// NAPI accepts and processes objects
static napi_value TestObject(napi_env env, napi_callback_info info) {
  size_t argc = 1;
  napi_value args[1] = {nullptr};
  napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

  napi_value name, age;
  napi_get_named_property(env, args[0], "name", &name);
  napi_get_named_property(env, args[0], "age", &age);

  size_t itemLength;
  napi_get_value_string_utf8(env, name, nullptr, 0, &itemLength);
  char *str = new char[itemLength + 1];
  napi_get_value_string_utf8(env, name, &str[0], itemLength + 1, &itemLength);
  OH_LOG_INFO(LOG_APP, "name is %{public}s", str);
  uint32_t num;
  napi_get_value_uint32(env, age, &num);
  OH_LOG_INFO(LOG_APP, "age is %{public}d", num);

  napi_value add;
  napi_get_named_property(env, args[0], "add", &add);

  // Create parameter array
  napi_value arr[2];
  napi_create_int32(env, 10, &arr[0]);
  napi_create_int32(env, 5, &arr[1]);

  napi_value result;
  uint32_t res;
  napi_call_function(env, args[0], add, 2, arr, &result);
  napi_get_value_uint32(env, result, &res);
  OH_LOG_INFO(LOG_APP, "res is %{public}d", res);

  return nullptr;
}
Enter fullscreen mode Exit fullscreen mode

C/C++ calls ArkTS:

  1. ArkTS passes callback methods to the NAPI side.
  2. NAPI creates a napi_value pointer-type object as a parameter for the callback method.
  3. ArkTS invokes the callback method to obtain and modify parameters passed from the NAPI side.
  4. The NAPI side retrieves and outputs the modified parameters.
Button("CallbackToArkTs")
  .onClick(() => {
    let da: Record<string, number> = testNapi.CallbackToArkTs((value: object) => {
      let data: Record<string, number> = value as Record<string, number>;
      console.info("修改前type: " + data["type"].toString())
      console.info(JSON.stringify(value))
      data["type"] += 10
      return value;
    });
    console.info(JSON.stringify(da))
  })
Enter fullscreen mode Exit fullscreen mode
static bool Napi_AddPropertyInt32(napi_env env, napi_value obj, const char *key, int32_t value) {
  napi_value key_napi = nullptr;
  napi_status status = napi_create_string_utf8(env, key, NAPI_AUTO_LENGTH, &key_napi);

  napi_value value_napi = nullptr;
  status = napi_create_int32(env, value, &value_napi);
  status = napi_set_property(env, obj, key_napi, value_napi);
  return true;
}

static napi_value CallbackToArkTs(napi_env env, napi_callback_info info) {

  // Get ArkTS parameters
  size_t argc = 1;
  napi_value js_cb = nullptr;
  napi_get_cb_info(env, info, &argc, &js_cb, nullptr, nullptr);

  // Native callback object to TS layer
  napi_value argv = nullptr;
  napi_create_object(env, &argv);
  Napi_AddPropertyInt32(env, argv, "type", 1);
  Napi_AddPropertyInt32(env, argv, "index", 2);

  // Native callback to TS layer
  napi_value result = nullptr;
  napi_call_function(env, NULL, js_cb, 1, &argv, &result);

  // Get the object modified by TS
  napi_value typeNumber = nullptr;
  napi_get_named_property(env, result, "type", &typeNumber);
  int32_t number;
  napi_get_value_int32(env, typeNumber, &number);
  OH_LOG_INFO(LOG_APP, "修改后type: %{public}d", number);

  // Return the modified object
  return result;
}
Enter fullscreen mode Exit fullscreen mode

5. How to Make a Horizontally Laid-out List Adapt to Content Height Automatically?

Top comments (0)