logo
0
0
WeChat Login

Node.js 调用 .NET AOT DLL 示例

本示例演示了如何在 Node.js 中调用 .NET AOT (Ahead-of-Time) 编译的 DLL 文件。

实现步骤

1. 编译 .NET AOT DLL

步骤 1: 创建 .NET 项目

dotnet new console -o DotNetAotLibrary cd DotNetAotLibrary

步骤 2: 添加 NativeExports.cs 文件

将示例中的 NativeExports.cs 文件添加到项目中。

步骤 3: 修改 csproj 文件

编辑 DotNetAotLibrary.csproj,修改以下配置:

<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Library</OutputType> <TargetFramework>net9.0</TargetFramework> <PublishAot>true</PublishAot> <AllowUnsafeBlocks>true</AllowUnsafeBlocks> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> </PropertyGroup> </Project>

步骤 4: 编译 AOT DLL

dotnet publish -c Release -r win-x64

编译完成后,DLL 文件将位于 bin/Release/net9.0/win-x64/publish/ 目录下。

2. 配置 Node.js 项目

步骤 1: 初始化项目

npm init -y

步骤 2: 安装依赖

npm install ffi-napi ref-napi

注意:如果安装 ffi-napi 时遇到构建错误,可能需要:

  • 安装 Visual Studio Build Tools
  • 确保 Python 3.10+ 已安装
  • 使用管理员权限运行命令提示符

3. 运行示例

示例 1: 使用基础脚本

  1. 修改 DLL 路径 编辑 call-aot-dll.js 文件,将 DLL 路径修改为实际编译后的路径(如果需要):

    const myAotLibrary = ffi.Library('./DotNetAotLibrary/bin/Release/net9.0/win-x64/publish/DotNetAotLibrary.dll', { // ... });
  2. 运行基础脚本

    node call-aot-dll.js

示例 2: 使用分组 API

  1. 使用分组 API 创建一个新的 JavaScript 文件,使用分组后的 API:

    const { Math, String, Json, Version } = require('./dotnet-api'); // 调用数学运算 console.log(Math.add(10, 20)); // 调用字符串处理 console.log(String.toUpper('hello')); // 调用 JSON 处理 const result = Json.processJson(JSON.stringify({ id: 1, name: '测试' })); console.log(result); // 调用版本获取 console.log(Version.getVersion());
  2. 运行分组 API 测试

    node test-dotnet-api.js

4. 项目结构

NodeApi/ ├── DotNetAotLibrary/ │ ├── NativeExports.cs # 主要导出功能 │ ├── MathExports.cs # 数学运算功能 │ ├── StringExports.cs # 字符串处理功能 │ └── DotNetAotLibrary.csproj # 项目配置 ├── call-aot-dll.js # 基础调用脚本 ├── dotnet-api.js # 分组 API 封装 ├── test-dotnet-api.js # 分组 API 测试 └── README.md # 项目说明文档

示例说明

C# 代码说明

  1. 多类导出设计

    • MathExports:数学运算方法(Add、Subtract、Multiply、Divide)
    • StringExports:字符串处理方法(GetLength、ToUpper、ToLower、Concat)
    • NativeExports:原始功能方法(CalculateSum、ProcessString、GetVersion、ProcessJsonData)
  2. 函数导出特性

    • 使用 [UnmanagedCallersOnly] 特性导出函数,指定 EntryPoint
    • 不同类的方法使用不同的命名前缀:Math_String_CalculateSum
    • 支持不同类型的参数和返回值
  3. UTF-8 字符串处理

    • StringToUtf8Ptr:将字符串转换为 UTF-8 编码的指针
    • Utf8PtrToString:从指针读取 UTF-8 编码的字符串
  4. JSON 序列化配置

    • 使用 JsonSourceGenerationOptions 配置 JSON 序列化
    • 支持中文编码、允许从字符串读取数字、支持尾随逗号
    • 属性名不区分大小写、写入 null 时忽略属性
    • 使用静态构造函数初始化 JsonSerializerContext,配置编码器支持所有 Unicode 范围

Node.js 代码说明

  1. 分组 API 设计

    • MathApi:封装数学运算方法
    • StringApi:封装字符串处理方法
    • JsonApi:封装 JSON 处理方法
    • VersionApi:封装版本信息获取方法
  2. FFI 调用

    • 使用 ffi-napi 模块加载和调用 DLL
    • 直接使用字符串类型作为参数,ffi-napi 自动处理指针转换
    • 直接接收字符串返回值,无需手动处理指针
  3. 内存管理

    • 自动处理内存分配和释放
    • 无需手动调用 FreeMemory 函数
  4. 异常处理

    • 添加异常处理确保程序稳定性
    • 支持中文数据的传输和处理

支持的类型映射

.NET 类型C 类型ffi-napi 类型
intint'int'
stringchar*'string'
boolbool'bool'
doubledouble'double'
IntPtrvoid*'pointer'

注意事项

  1. 确保 .NET 和 Node.js 运行时架构一致(都是 x64 或都是 x86)
  2. 字符串处理使用自定义的 UTF-8 编码实现,支持中文
  3. 必须调用 FreeMemory 函数释放 DLL 中分配的内存,避免内存泄漏
  4. 异常处理确保程序稳定性
  5. 需要将 OutputType 设置为 Library 而不是 Exe
  6. 使用 JsonSourceGenerationOptions 配置 JSON 序列化,支持多种高级选项
  7. 配置了编码器支持所有 Unicode 范围,确保中文正常显示
  8. 使用静态构造函数初始化 JsonSerializerContext,确保配置正确应用

参考资料

About

No description, topics, or website provided.
Language
C#64.3%
JavaScript35.7%