.NET 7 AOT 的使用以及 .NET 与 Go 互相调用( 四 )


文章插图
在 C 语言中 , 导出一个函数的格式可以这样:
// MyCFuncs.h#ifdef __cplusplusextern "C" {// only need to export C interface if// used by C++ source code#endif__declspec( dllimport ) void MyCFunc();__declspec( dllimport ) void AnotherCFunc();#ifdef __cplusplus}#endif当代码编译之后 , 我们就可以通过引用生成的库文件 , 调用 MyCFuncAnotherCFunc 两个方法 。
如果不导出的话 , 别的程序是无法调用库文件里面的函数 。
因为 .NET 7 的 AOT 做了很多改进 , 因此 , .NET 程序也可以导出函数了 。
新建一个项目 , 名字就叫 CsharpExport 吧 , 我们接下来就在这里项目中编写我们的动态链接库 。
添加一个 CsharpExport.cs 文件 , 内容如下:
using System.Runtime.InteropServices;namespace CsharpExport{public class Export{[UnmanagedCallersOnly(EntryPoint = "Add")]public static int Add(int a, int b){return a + b;}}}然后在 .csproj 文件中 , 加上 PublishAot 选项 。

.NET 7 AOT 的使用以及 .NET 与 Go 互相调用

文章插图
然后通过以下命令发布项目 , 生成链接库:
dotnet publish -p:NativeLib=Shared -r win-x64 -c Release
.NET 7 AOT 的使用以及 .NET 与 Go 互相调用

文章插图
看起来还是比较大 , 为了继续裁剪体积 , 我们可以在 CsharpExport.csproj 中加入以下配置 , 以便生成更小的可执行文件 。
<!--AOT 相关--><PublishAot>true</PublishAot><TrimMode>full</TrimMode><RunAOTCompilation>True</RunAOTCompilation><PublishTrimmed>true</PublishTrimmed><TrimmerRemoveSymbols>true</TrimmerRemoveSymbols><PublishReadyToRunEmitSymbols>false</PublishReadyToRunEmitSymbols><DebuggerSupport>false</DebuggerSupport><EnableUnsafeUTF7Encoding>true</EnableUnsafeUTF7Encoding><InvariantGlobalization>true</InvariantGlobalization><HttpActivityPropagationSupport>false</HttpActivityPropagationSupport><MetadataUpdaterSupport>true</MetadataUpdaterSupport><UseSystemResourceKeys>true</UseSystemResourceKeys><IlcDisableReflection >true</IlcDisableReflection>
.NET 7 AOT 的使用以及 .NET 与 Go 互相调用

文章插图
C# 调用 C# 生成的 AOT在本小节中 , 将使用 CsharpAot 项目调用 CsharpExport 生成的动态链接库 。
CsharpExport.dll 复制到 CsharpAot 项目中 , 并配置 始终复制 。
.NET 7 AOT 的使用以及 .NET 与 Go 互相调用

文章插图
CsharpAotNative 中加上:
[LibraryImport("CsharpExport.dll", SetLastError = true)][return: MarshalAs(UnmanagedType.I4)]internal static partial Int32 Add(Int32 a, Int32 b);
.NET 7 AOT 的使用以及 .NET 与 Go 互相调用

文章插图
然后在代码中使用:
static void Main(){var result = Native.Add(1, 2);Console.WriteLine($"1 + 2 = {result}");Console.ReadKey();}在 Visual Studio 里启动 Debug 调试:
.NET 7 AOT 的使用以及 .NET 与 Go 互相调用

文章插图
可以看到 , 是正常运行的 。
接着 , 将 CsharpAot 项目发布为 AOT 后 , 再次执行:
.NET 7 AOT 的使用以及 .NET 与 Go 互相调用

文章插图
可以看到 , .NET AOT 调用 .NET AOT 的代码是没有问题的 。

经验总结扩展阅读