











import pascalbridge from 'libpascalbridge.so'; // 导入 C++ 模块 @Entry @Component struct Index { private xComponentController: XComponentController = new XComponentController(); build() { Column() { XComponent({ id: 'xcomponentId', type: XComponentType.SURFACE, libraryname: 'pascalbridge', controller: this.xComponentController }) .onLoad(() => { // ★ 获取 XComponent 的 Surface ID (字符串形式) let surfaceId = this.xComponentController.getXComponentSurfaceId(); console.log("Lazarus ArkTS: surfaceId = " + surfaceId); // ★ 将 Surface ID 传递给 C++ 端 pascalbridge.setSurfaceId(surfaceId); }) .width('100%') .height('100%') } .width('100%') .height('100%') } }
#include <native_window/external_window.h> #include <sys/mman.h> #include <unistd.h> #include <cstring> #include <cstdlib> #include "hilog/log.h" #include "napi/native_api.h" // 声明 Pascal 导出的函数 extern "C" { void DoDraw(); void* GetBitmapPixels(); } static OHNativeWindow* g_nativeWindow = nullptr; void RenderToScreen() { if (!g_nativeWindow) { OH_LOG_Print(LOG_APP, LOG_ERROR, 0xFF00, "Lazarus", "Render Failed: g_nativeWindow is NULL!"); return; } DoDraw(); void* pixels = GetBitmapPixels(); if (!pixels) { OH_LOG_Print(LOG_APP, LOG_ERROR, 0xFF00, "Lazarus", "Render Failed: GetBitmapPixels returned NULL!"); return; } OHNativeWindowBuffer* buffer = nullptr; Region::Rect rect = {0, 0, 400, 400}; Region region = {&rect, 1}; int ret = OH_NativeWindow_LockBuffer(g_nativeWindow, region, &buffer); if (ret != 0 || !buffer) { OH_LOG_Print(LOG_APP, LOG_ERROR, 0xFF00, "Lazarus", "Render Failed: LockBuffer failed, ret=%{public}d", ret); return; } BufferHandle* bufferHandle = OH_NativeWindow_GetBufferHandleFromNative(buffer); if (!bufferHandle) { OH_LOG_Print(LOG_APP, LOG_ERROR, 0xFF00, "Lazarus", "Render Failed: GetBufferHandle failed!"); return; } OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00, "Lazarus", "Buffer Info: w=%{public}d, h=%{public}d, stride=%{public}d", bufferHandle->width, bufferHandle->height, bufferHandle->stride); void* mappedAddr = mmap(nullptr, bufferHandle->size, PROT_READ | PROT_WRITE, MAP_SHARED, bufferHandle->fd, 0); if (mappedAddr == MAP_FAILED) { OH_LOG_Print(LOG_APP, LOG_ERROR, 0xFF00, "Lazarus", "Render Failed: mmap failed!"); return; } uint32_t* srcLine = (uint32_t*)pixels; uint8_t* dstLine = (uint8_t*)mappedAddr; uint32_t stride = bufferHandle->width * 4; for (int y = 0; y < 400; y++) { memcpy(dstLine, srcLine, 400 * 4); srcLine += 400; dstLine += stride; } munmap(mappedAddr, bufferHandle->size); ret = OH_NativeWindow_UnlockAndFlushBuffer(g_nativeWindow); if (ret != 0) { OH_LOG_Print(LOG_APP, LOG_ERROR, 0xFF00, "Lazarus", "Render Failed: UnlockAndFlushBuffer failed, ret=%{public}d", ret); } else { OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00, "Lazarus", "Render Success!"); } } // ============== 接收 SurfaceId 的 NAPI 函数 ============== static napi_value SetSurfaceId(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); size_t strSize = 0; napi_get_value_string_utf8(env, args[0], nullptr, 0, &strSize); char* surfaceIdStr = new char[strSize + 1]; napi_get_value_string_utf8(env, args[0], surfaceIdStr, strSize + 1, &strSize); OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00, "Lazarus", "Received SurfaceId string: %{public}s", surfaceIdStr); // 将字符串转为 uint64_t uint64_t surfaceId = strtoull(surfaceIdStr, nullptr, 10); delete[] surfaceIdStr; // ★ 根据头文件,创建 NativeWindow 的正确函数 ★ int32_t ret = OH_NativeWindow_CreateNativeWindowFromSurfaceId(surfaceId, &g_nativeWindow); if (ret != 0 || !g_nativeWindow) { OH_LOG_Print(LOG_APP, LOG_ERROR, 0xFF00, "Lazarus", "CreateNativeWindowFromSurfaceId failed, ret=%{public}d", ret); } else { OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00, "Lazarus", "CreateNativeWindowFromSurfaceId Success!"); RenderToScreen(); } return nullptr; } extern "C" __attribute__((visibility("default"))) napi_value Init(napi_env env, napi_value exports) { napi_property_descriptor desc[] = { { "setSurfaceId", nullptr, SetSurfaceId, nullptr, nullptr, nullptr, napi_default, nullptr } }; napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); return exports; } static napi_module demoModule = { .nm_version = 1, .nm_flags = 0, .nm_filename = nullptr, .nm_register_func = Init, .nm_modname = "pascalbridge", .nm_priv = ((void*)0), .reserved = { 0 }, }; extern "C" __attribute__((constructor)) void RegisterModule(void) { napi_module_register(&demoModule); }
cmake_minimum_required(VERSION 3.5) project(pascalbridge) # === 让CMake能找到SDK自带的系统库 === if(DEFINED PACKAGE_FIND_FILE) include(${PACKAGE_FIND_FILE}) endif() add_library(pascalbridge SHARED native_module.cpp) # 设置预构建库路径 set(PREBUILT_LIB_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libs/${OHOS_ARCH}) # 将预构建 so 安装到 libs 目录,使其被打包 install(FILES ${PREBUILT_LIB_DIR}/libOHOS_Lazarus.so DESTINATION libs/${OHOS_ARCH}) # === 1. 指定 Pascal 动态库的搜索路径 === # 假设您把 Pascal 编译的 .so 放在了 cpp/libs/arm64-v8a 和 cpp/libs/x86_64 下 # ${OHOS_ARCH} 会自动替换为 arm64-v8a 或 x86_64 target_link_directories(pascalbridge PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/libs/${OHOS_ARCH}) # === 2. 链接所有需要的库 === # 注意:CMake规范中,链接库不需要加 lib 前缀和 .so 后缀 target_link_libraries(pascalbridge PUBLIC ace_napi.z dl hilog_ndk.z native_window OHOS_Lazarus # ★ 新增:链接你的 Pascal 动态库 )
entry
└── libs/ --->打包hap需要的so
├── arm64-v8a/ <-- 真机架构
│ └── libOHOS_QT_Lazarus.so <-- Lazarus编译出的arm64版本
└── x86_64/ <-- 模拟器架构
└── libOHOS_QT_Lazarus.so <-- Lazarus编译出的x86_64版本
entry/src/main/cpp/ ---->链接时需要的so
├── CMakeLists.txt
├── native_module.cpp
└── libs/
├── arm64-v8a/ <-- 真机架构
│ └── libOHOS_QT_Lazarus.so <-- Lazarus编译出的arm64版本
└── x86_64/ <-- 模拟器架构
└── libOHOS_QT_Lazarus.so <-- Lazarus编译出的x86_64版本
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。