Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

C# 生成动态库

说明

  • 本页记录使用 .NET 8AOT 方式生成可被 C 语言直接调用的动态库.
  • 适合做 C# -> 原生导出 的最小验证, 也适合给 C/C++ 或其他语言调用 .NET 逻辑时做桥接实验.

目标

  • 使用 .NET 8 类库项目.
  • UnmanagedCallersOnly 暴露导出函数.
  • 通过 PublishAot + NativeLib=Shared 生成共享库.

基本步骤

  1. 使用 Visual Studio 2022 创建 .NET 8 类库 项目.
  2. 在导出函数上使用 UnmanagedCallersOnly.
  3. 打开 PublishAot 并以共享库方式发布.
  4. 在调用侧根据导出名和调用约定加载动态库.

示例代码

using System.Runtime.InteropServices;

namespace TestCSharpLib
{
    public class OneClass
    {
        [UnmanagedCallersOnly(EntryPoint = "Add")]
        public static int Add(int a, int b)
        {
            return a + b;
        }

        [UnmanagedCallersOnly(EntryPoint = "Greet")]
        public static void Greet()
        {
            Console.WriteLine("你好呀");
        }
    }
}

项目配置示例

<PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <PublishAot>true</PublishAot>
    <PlatformTarget>x64</PlatformTarget>
    <OutputType>Library</OutputType>
</PropertyGroup>

发布命令

dotnet publish -p:NativeLib=Shared -r win-x64 -c Release

输出目录

bin/Release/net8.0/win-x64/native/

常见注意点

  • 导出函数签名要尽量简单稳定, 先从整数, 指针或明确定义的结构体开始.
  • 调用侧和生成侧的架构必须一致, 例如都使用 x64.
  • 字符串, 内存释放和异常边界要提前约定清楚, 避免跨语言调用时出现未定义行为.
  • 若只想在 C# 内部复用逻辑, 并不需要走原生动态库导出方案.