C# NativeAOT生成.so 库供Linux下C++调用

C# NativeAOT生成.so 库供Linux下C++调用

#nativeAOT

✅ 最终目标

使用 C# 编写 Add(int a, int b) → 编译为 libadd.so → 在 Linux C++ 中通过 dlopen + dlsym 调用


🧱 第 1 步:创建 NativeAOT 项目

 
 
 
xxxxxxxxxx
 
 
 
 
dotnet new classlib -n AddLibrary
cd AddLibrary
 

📄 修改 AddLibrary.csproj

编辑 AddLibrary.csproj 文件,设置为使用 NativeAOT 编译:

 
 
 
xxxxxxxxxx
 
 
 
 
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Library</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <PublishAot>true</PublishAot>
    <SelfContained>true</SelfContained>
    <UseNativeAot>true</UseNativeAot>
  </PropertyGroup>
</Project>
 

🧠 第 2 步:编写导出函数(Add)

创建或替换 Class1.cs 文件内容如下:

 
 
 
​x
 
 
 
 
using System;
using System.Runtime.InteropServices;

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

🛠 第 3 步:在 Linux 或 WSL 中发布为 .so(WSL为例)

🛠️ 安装WSL
 
 
 
xxxxxxxxxx
 
 
 
 
wsl --install
 
🛠️WSL下安装配置dotnet库
 
 
 
xxxxxxxxxx
 
 
 
 
wget https://dotnet.microsoft.com/download/dotnet/scripts/v1/dotnet-install.sh
chmod +x dotnet-install.sh
./dotnet-install.sh --version 8.0.204
 
🛠️配置环境变量

你只需在终端执行(或添加到 ~/.bashrc / ~/.zshrc):

 
 
 
xxxxxxxxxx
 
 
 
 
export DOTNET_ROOT=$HOME/.dotnet export PATH=$PATH:$HOME/.dotnet:$HOME/.dotnet/tools
 

然后运行:

 
 
 
xxxxxxxxxx
 
 
 
 
source ~/.bashrc  # 或 ~/.zshrc,如果你用的是 zsh
 

确认安装成功:

 
 
 
xxxxxxxxxx
 
 
 
 
dotnet --version
 

✅ 输出 8.0.204 即成功!

🛠️安装构建环境
 
 
 
xxxxxxxxxx
 
 
 
 
sudo apt update
sudo apt install -y build-essential clang zlib1g-dev
 

解释:

  • build-essential:包含 gcc, g++, make, ld 等工具
  • clang:LLVM 链接器(NativeAOT 优先使用)
  • zlib1g-dev:NativeAOT 部分场景下需要

验证是否安装成功

 
 
 
xxxxxxxxxx
 
 
 
 
gcc --version
clang --version
 

必须在 Linux 或 WSL 环境下 执行: 示例:项目位于 d:/Work/Test/NativeAOT/ULib

 
 
 
xxxxxxxxxx
 
 
 
 
cd /mnt/d/Work/Test/NativeAOT/ULib
dotnet publish -c Release -r linux-x64
 

输出文件位于:

 
 
 
xxxxxxxxxx
 
 
 
 
bin/Release/net8.0/linux-x64/native/AddLibrary.so
 

可重命名为:

 
 
 
xxxxxxxxxx
 
 
 
 
cp bin/Release/net8.0/linux-x64/native/AddLibrary.so ./libadd.so
 

✅ 第 4 步:用 C++ 调用 libadd.so

创建一个 main.cpp

 
 
 
xxxxxxxxxx
 
 
 
 
#include <iostream>
#include <dlfcn.h>

typedef int (*AddFunc)(int, int);

int main() {
    //加载当前目录下的libadd.so
    void* handle = dlopen("./libadd.so", RTLD_NOW);
    if (!handle) {
        std::cerr << "Failed to load .so: " << dlerror() << std::endl;
        return 1;
    }

    AddFunc add = (AddFunc)dlsym(handle, "Add");
    if (!add) {
        std::cerr << "Failed to find symbol: " << dlerror() << std::endl;
        dlclose(handle);
        return 2;
    }

    int result = add(10, 20);
    std::cout << "✅ Add(10, 20) = " << result << std::endl;

    dlclose(handle);
    return 0;
}
 

🧪 第 5 步:编译并运行 C++ 调用测试

确保在main.cpplibadd.so所在的目录中运行

 
 
 
xxxxxxxxxx
 
 
 
 
g++ main.cpp -o testadd -ldl
./testadd
 

输出:

 
 
 
xxxxxxxxxx
 
 
 
 
✅ Add(10, 20) = 30
 

📦 最终结构示意

 
 
 
xxxxxxxxxx
 
 
 
 
AddLibrary/
├── AddLibrary.csproj
├── Class1.cs  (含 Add 方法)
├── bin/
│   └── Release/...
├── libadd.so  <-- 编译后复制出来
└── main.cpp   <-- 调用测试
 

✅ 额外建议

目标操作
自动编译 .so + 测试build.sh 脚本
发布 Windows .dll-r win-x64
多函数导出增加多个 [UnmanagedCallersOnly(EntryPoint = "...")]
高性能避免复杂对象,使用基本类型指针(int, float*)

✅ 总结命令回顾

 
 
 
 
 
 
 
 
dotnet new classlib -n AddLibrary
# 编辑代码 & csproj
dotnet publish -c Release -r linux-x64
g++ main.cpp -o testadd -ldl
./testadd
 

 

原创作者: Firepad-magic 转载于: https://www.cnblogs.com/Firepad-magic/p/18912554
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值