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.cpp 和libadd.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