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, ¶m, &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