惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Y
Y Combinator Blog
V
V2EX
Jina AI
Jina AI
爱范儿
爱范儿
M
MIT News - Artificial intelligence
量子位
L
LangChain Blog
Google DeepMind News
Google DeepMind News
酷 壳 – CoolShell
酷 壳 – CoolShell
罗磊的独立博客
腾讯CDC
MongoDB | Blog
MongoDB | Blog
P
Proofpoint News Feed
宝玉的分享
宝玉的分享
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Last Week in AI
Last Week in AI
H
Hackread – Cybersecurity News, Data Breaches, AI and More
F
Fortinet All Blogs
The GitHub Blog
The GitHub Blog
Engineering at Meta
Engineering at Meta
博客园 - 聂微东
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Vercel News
Vercel News
T
The Blog of Author Tim Ferriss

博客园 - 秋·风

修复lazarus datetimepicker控件在linux下拉不能选择日期的bug 用fpc trunk编译lazarus控件找不到TTimeZone 在银河麒麟v10操作系统应用程序执行遇到“权限不够”的提示 修复pl_cindy的Panel系列控件在gtk3出错的bug 龙芯 3A4000工具链的编译(mingw64) lazarus 4.8及之前的版本QT5中文输入多字词组时只输入前2个中文 修正lazarus在GTK3下的Synedit只能输入2个中文字符的Bug lazarus trunk linux从2026.07.02开始,LCLWidgetType默认使用gtk3,怎样改回gtk2 【aarch64-win64】DonAlfredo终于修复fpc将TSmallPoint赋值为一个负数,并将TSmallPoint赋值给TPoint时得到一个655xx的数值的bug lazarus编译时提示链接出错的处理方法 mORMot2两个BUG 【aarch64-win64】发现fpc aarch64-win64 将TSmallPoint赋值为一个负数,并赋值给TPoint时得到一个655xx的数值的bug 修复aarch64 win64下lazarus不弹出SourceTabPopUpMenu fpc aarch64-win64版编译应用时遇到一个奇怪的bug 在windows 11 on arm64系统编译lazarus出错的处理方法 修复TDBMemo只读不能使用Ctrl+C复制文字的Bug freepascal打补丁后已支持windows 11 on arm64(lazarus aarch64 windows版也可以运行了) 查看libc.so.6的版本号 Lazarus移动版启动程序 fpc 3.2.2交叉编译i386-linux链接出错 lazarus鸿蒙开发13:使用鸿蒙原生API画图--lazarus侧关键代码 lazarus鸿蒙开发11:使用鸿蒙原生接口画图 lazarus鸿蒙开发10:lazarus一键编译、打包助手 lazarus鸿蒙开发9:使用命令行编译DevEco Studio应用 lazarus鸿蒙开发8:在DevEco Studio的日志窗口显示日志信息 lazarus鸿蒙开发7:在 Windows 上为 OpenHarmony (LoongArch64) 编译 Qt 5.15.12 SDK 指南 lazarus鸿蒙开发6:鸿蒙project配置 lazarus鸿蒙开发5:编译ohos_hap_project lazarus鸿蒙开发4:编译OHOS_QT_Lazarus lazarus鸿蒙开发3:编译libLazarusOHOS_Wrapper.so
lazarus鸿蒙开发12:使用鸿蒙原生API画图--鸿蒙侧关键代码
秋·风 · 2026-06-10 · via 博客园 - 秋·风
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版本