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_IsFunction | Checks whether an object is a function object.| 18| OH_JSVM_CreateFunction | Creates a JS function to call a C/C++ function in JS environment. The function can be called only after it is set in a JS object.| 19 20## Example 21 22If you are just starting out with JSVM-API, see [JSVM-API Development Process](use-jsvm-process.md). The following demonstrates only the C++ code involved in creating and calling functions. 23 24### OH_JSVM function Test 25 26Full code for the CPP test. The entry is **TEST_FUNC**. 27``` cpp 28#include "hilog/log.h" 29#include "ark_runtime/jsvm.h" 30 31#define LOG_DOMAIN 0x3200 32#define LOG_TAG "APP" 33 34#define CHECK_RET(cond) \ 35 if ((cond)) { \ 36 const JSVM_ExtendedErrorInfo* info; \ 37 OH_JSVM_GetLastErrorInfo(env, &info); \ 38 OH_LOG_ERROR(LOG_APP, "jsvm fail file: %{public}s line: %{public}d ret = %{public}d message = %{public}s", __FILE__, __LINE__, cond, info != nullptr ? info->errorMessage : ""); \ 39 return -1; \ 40 } 41 42#define CHECK(cond) \ 43 if (!(cond)) { \ 44 OH_LOG_ERROR(LOG_APP, "jsvm fail file: %{public}s line: %{public}d ret = %{public}d", __FILE__, __LINE__, cond); \ 45 return -1; \ 46 } 47 48JSVM_Value NativeCreateFunctionTest(JSVM_Env env, JSVM_CallbackInfo info) { 49 void *data; 50 size_t argc = 1; 51 JSVM_Value argv[1] = {nullptr}; 52 JSVM_Value thisArg; 53 // Obtain the callback parameters. 54 JSVM_Status ret = OH_JSVM_GetCbInfo(env, info, &argc, &argv[0], &thisArg, &data); 55 if (ret != JSVM_OK) { 56 const JSVM_ExtendedErrorInfo* info; 57 OH_JSVM_GetLastErrorInfo(env, &info); 58 OH_LOG_ERROR(LOG_APP, "jsvm fail file: %{public}s line: %{public}d ret = %{public}d message = %{public}s", __FILE__, __LINE__, ret, info != nullptr ? info->errorMessage : ""); 59 return nullptr; 60 } 61 char message[256]; 62 OH_JSVM_GetValueStringLatin1(env, argv[0], message, 256, nullptr); 63 if (data == nullptr) { 64 OH_LOG_ERROR(LOG_APP, "jsvm: %{public}s; callback data null", message); 65 } else { 66 OH_LOG_INFO(LOG_APP, "jsvm: %{public}s; %{public}s", message, (char*)data); 67 } 68 return nullptr; 69} 70 71static int32_t TEST_FUNC() { 72 JSVM_InitOptions initOptions{}; 73 JSVM_VM vm; 74 JSVM_Env env = nullptr; 75 JSVM_VMScope vmScope; 76 JSVM_EnvScope envScope; 77 JSVM_HandleScope handleScope; 78 JSVM_Value result; 79 static bool isVMInit = false; 80 if (!isVMInit) { 81 isVMInit = true; 82 // A single process needs to be initialized only once. 83 OH_JSVM_Init(&initOptions); 84 } 85 CHECK_RET(OH_JSVM_CreateVM(nullptr, &vm)); 86 CHECK_RET(OH_JSVM_CreateEnv(vm, 0, nullptr, &env)); 87 CHECK_RET(OH_JSVM_OpenVMScope(vm, &vmScope)); 88 CHECK_RET(OH_JSVM_OpenEnvScope(env, &envScope)); 89 CHECK_RET(OH_JSVM_OpenHandleScope(env, &handleScope)); 90 91 // Create a function and check it. 92 char hello[] = "Hello World!"; 93 JSVM_CallbackStruct cb = {NativeCreateFunctionTest, (void*)hello}; 94 JSVM_Value func; 95 CHECK_RET(OH_JSVM_CreateFunction(env, "", JSVM_AUTO_LENGTH, &cb, &func)); 96 bool isFunction = false; 97 CHECK_RET(OH_JSVM_IsFunction(env, func, &isFunction)); 98 CHECK(isFunction); 99 100 // Set the function to a global object. 101 JSVM_Value global; 102 CHECK_RET(OH_JSVM_GetGlobal(env, &global)); 103 JSVM_Value key; 104 CHECK_RET(OH_JSVM_CreateStringUtf8(env, "NativeFunc", JSVM_AUTO_LENGTH, &key)); 105 CHECK_RET(OH_JSVM_SetProperty(env, global, key, func)); 106 107 // Call the function through OH_JSVM_CallFunction. 108 JSVM_Value argv[1] = {nullptr}; 109 OH_JSVM_CreateStringUtf8(env, "jsvm api call funtion", JSVM_AUTO_LENGTH, &argv[0]); 110 CHECK_RET(OH_JSVM_CallFunction(env, global, func, 1, argv, &result)); 111 112 // Call the function through the script. 113 JSVM_Script script; 114 JSVM_Value jsSrc; 115 const char* srcCallNative = R"JS(NativeFunc('js source call funtion');)JS"; 116 CHECK_RET(OH_JSVM_CreateStringUtf8(env, srcCallNative, JSVM_AUTO_LENGTH, &jsSrc)); 117 CHECK_RET(OH_JSVM_CompileScript(env, jsSrc, nullptr, 0, true, nullptr, &script)); 118 CHECK_RET(OH_JSVM_RunScript(env, script, &result)); 119 120 CHECK_RET(OH_JSVM_CloseHandleScope(env, handleScope)); 121 CHECK_RET(OH_JSVM_CloseEnvScope(env, envScope)); 122 CHECK_RET(OH_JSVM_CloseVMScope(vm, vmScope)); 123 CHECK_RET(OH_JSVM_DestroyEnv(env)); 124 CHECK_RET(OH_JSVM_DestroyVM(vm)); 125 return 0; 126} 127``` 128**Expected output** 129``` 130jsvm: jsvm api call funtion; Hello World! 131jsvm: js source call funtion; Hello World! 132``` 133