• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Creating and Calling JS Functions Using JSVM-API
2
3## Introduction
4
5JSVM-API provides APIs for calling JavaScript (JS) functions and passing parameters or creating JS methods in C/C++.
6
7## Basic Concepts
8
9Functions are blocks of reusable code that performs specific tasks or operations. You can define functions to implement different operations. Functions provide a way to modularize and structure code, helping make your code more organized, reusable, and maintainable.
10
11## Available APIs
12
13| API                      | Description                      |
14|----------------------------|--------------------------------|
15| OH_JSVM_GetCbInfo          | Obtains detailed information about the call, such as the parameters and **this** pointer, from the given callback information.|
16| OH_JSVM_CallFunction       | Calls a JS function from a C/C++ addon.|
17| OH_JSVM_CreateFunction     | Creates a JS function object in native code, which allows calling into the native code from JS.|
18
19## Example
20
21If you are just starting out with JSVM-API, see [JSVM-API Development Process](use-jsvm-process.md). The following demonstrates only the C++ and ArkTS code related to the APIs for creating and calling JS functions.
22
23### OH_JSVM_GetCbInfo
24
25Use **OH_JSVM_GetCbInfo** to obtain detailed information about function calls.
26
27CPP code:
28
29```cpp
30// hello.cpp
31#include "napi/native_api.h"
32#include "ark_runtime/jsvm.h"
33#include <hilog/log.h>
34// Register the GetCbArgs callback.
35static JSVM_CallbackStruct param[] = {
36    {.data = nullptr, .callback = GetCbArgs},
37};
38static JSVM_CallbackStruct *method = param;
39// Set a property descriptor named getCbArgs and associate it with a callback. This allows the GetCbArgs callback to be called from JS.
40static JSVM_PropertyDescriptor descriptor[] = {
41    {"getCbArgs", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
42};
43// Define OH_JSVM_GetCbInfo.
44static JSVM_Value GetCbArgs(JSVM_Env env, JSVM_CallbackInfo info)
45{
46    size_t argc = 1;
47    JSVM_Value args[1] = {nullptr};
48    JSVM_Status status = OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
49    if (status != JSVM_OK) {
50        OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_GetCbInfo: failed");
51        return nullptr;
52    }
53    // In this example, an 8-byte buffer is set. Set the buffer size based on service requirements.
54    size_t bufSize = 8;
55    char buf[bufSize];
56    size_t result = 0;
57    OH_JSVM_GetValueStringUtf8(env, args[0], buf, bufSize, &result);
58    OH_LOG_INFO(LOG_APP, "JSVM args[0] is: %{public}s", buf);
59    return args[0];
60}
61```
62
63ArkTS code:
64
65```ts
66import hilog from "@ohos.hilog"
67// Import the native APIs.
68import napitest from "libentry.so"
69let script: string = `
70   const str = 'message';
71   getCbArgs(str);
72  `;
73try {
74  let result = napitest.runJsVm(script);
75  hilog.info(0x0000, 'JSVM', 'GetCbArgs:%{public}s', result);
76} catch (error) {
77  hilog.error(0x0000, 'JSVM', 'GetCbArgs: %{public}s', error.message);
78}
79```
80
81### OH_JSVM_CallFunction
82
83Use **OH_JSVM_CallFunction** to call a JS function from a C/C++ addon.
84
85CPP code:
86
87```cpp
88// hello.cpp
89#include "napi/native_api.h"
90#include "ark_runtime/jsvm.h"
91#include <hilog/log.h>
92// Register the CallFunction callback.
93static JSVM_CallbackStruct param[] = {
94    {.data = nullptr, .callback = CallFunction},
95};
96static JSVM_CallbackStruct *method = param;
97// Set a property descriptor named callFunction and associate it with a callback. This allows the CallFunction callback to be called from JS.
98static JSVM_PropertyDescriptor descriptor[] = {
99    {"callFunction", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
100};
101// Define OH_JSVM_CallFunction.
102static JSVM_Value CallFunction(JSVM_Env env, JSVM_CallbackInfo info)
103{
104    size_t argc = 1;
105    JSVM_Value args[1] = {nullptr};
106    // Obtain the parameters passed from JS.
107    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
108    // Obtain the global object. Here, global is used because the second parameter of OH_JSVM_CallFunction is the input parameter this of the JS function.
109    JSVM_Value global;
110    OH_JSVM_GetGlobal(env, &global);
111    // Call the JS method.
112    JSVM_Value result = nullptr;
113    JSVM_Status status = OH_JSVM_CallFunction(env, global, args[0], 0, nullptr, &result);
114    if (status != JSVM_OK) {
115        OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_CallFunction: failed");
116        return nullptr;
117    }
118    // Print the execution result of the JS method.
119    int32_t resultValue = 0;
120    OH_JSVM_GetValueInt32(env, result, &resultValue);
121    OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_CallFunction reslut is: %{public}d", resultValue);
122    OH_LOG_INFO(LOG_APP, "If the resultValue is 10, the example runs successfully");
123    return result;
124}
125```
126
127ArkTS code:
128
129```ts
130import hilog from "@ohos.hilog"
131// Import the native APIs.
132import napitest from "libentry.so"
133let script: string = `
134    function returnNumber(){
135        return 10;
136    }
137    callFunction(returnNumber)
138`
139try {
140  let result = napitest.runJsVm(script);
141  hilog.info(0x0000, 'testJSVM', 'Test JSVM callFunction: %{public}s', result);
142} catch (error) {
143  hilog.error(0x0000, 'testJSVM', 'Test JSVM callFunction error: %{public}s', error.message);
144}
145```
146
147### OH_JSVM_CreateFunction
148
149Use **OH_JSVM_CreateFunction** to create a JS function object in native code, which allows calling into the native code from JS.
150
151CPP code:
152
153```cpp
154// hello.cpp
155#include "napi/native_api.h"
156#include "ark_runtime/jsvm.h"
157#include <hilog/log.h>
158// Register the CreateFunction callback.
159static JSVM_CallbackStruct param[] = {
160    {.data = nullptr, .callback = CreateFunction},
161};
162static JSVM_CallbackStruct *method = param;
163// Set a property descriptor named createFunction and associate it with a callback. This allows the CreateFunction callback to be called from JS.
164static JSVM_PropertyDescriptor descriptor[] = {
165    {"createFunction", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
166};
167// Define the CalculateArea function.
168static JSVM_Value CalculateArea(JSVM_Env env, JSVM_CallbackInfo info)
169{
170    // Obtain the two parameters passed from JS.
171    size_t argc = 2;
172    JSVM_Value args[2] = {nullptr};
173    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
174    double width;
175    OH_JSVM_GetValueDouble(env, args[0], &width);
176    double height;
177    OH_JSVM_GetValueDouble(env, args[1], &height);
178    JSVM_Value area;
179    OH_JSVM_CreateDouble(env, width * height, &area);
180    return area;
181}
182static double width = 1.4;
183static double height = 5.0;
184// Define OH_JSVM_CreateFunction.
185static JSVM_Value CreateFunction(JSVM_Env env, JSVM_CallbackInfo info) {
186    // Create a callback struct named param and pass in OH_JSVM_CreateFunction.
187    JSVM_CallbackStruct param;
188    param.data = nullptr;
189    param.callback = CalculateArea;
190    JSVM_Value funcValue = nullptr;
191    // Create a JS function named calculateArea.
192    JSVM_Status status = OH_JSVM_CreateFunction(env, "calculateArea", JSVM_AUTO_LENGTH, &param, &funcValue);
193    if (funcValue == nullptr || status != JSVM_OK) {
194        OH_JSVM_ThrowError(env, nullptr, "JSVM OH_JSVM_CreateFunction failed");
195    }
196    // Create parameters.
197    JSVM_Value args[2] = {nullptr};
198    OH_JSVM_CreateDouble(env, width, &args[0]);
199    OH_JSVM_CreateDouble(env, height, &args[1]);
200    JSVM_Value global;
201    OH_JSVM_GetGlobal(env, &global);
202    // Call the calculateArea function and pass in parameters.
203    JSVM_Value ret = nullptr;
204    OH_JSVM_CallFunction(env, global, funcValue, 2, args, &ret);
205    // Return the execution result of the calculateArea function.
206    int32_t result = 0;
207    OH_JSVM_GetValueInt32(env, ret, &result);
208    OH_LOG_INFO(LOG_APP, "JSVM If 7 is printed here, the use case is correct: %{public}d", result);
209    return ret;
210}
211```
212
213ArkTS code:
214
215```ts
216import hilog from "@ohos.hilog"
217// Import the native APIs.
218import napitest from "libentry.so"
219let script: string = `createFunction()`;
220try {
221  let result = napitest.runJsVm(script);
222  hilog.info(0x0000, 'testJSVM', 'Test JSVM createFunction: %{public}s', result);
223} catch (error) {
224  hilog.error(0x0000, 'testJSVM', 'Test JSVM createFunction error: %{public}s', error.message);
225}
226```
227