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

在 .NET 中 string 是引用类型 , 而在 Go 语言中 string 是值类型 , 这个代码执行后 , 会出现什么结果呢?

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

文章插图
执行结果是输出一个长数字 。
笔者不太了解 Golang 内部的原理 , 不确定这个数字是不是 .NET string 传递了指针地址 , 然后 Go 把指针地址当字符串打印出来了 。
因为在 C、Go、.NET 等语言中 , 关于 char、string 的内部处理方式不一样 , 因此这里的传递方式导致了跟我们的预期结果不一样 。
接着 , 我们将 main.go 文件的 Start 函数改成:
//export Startfunc Start(a,b int) int{ return a+b}然后执行命令重新生成动态链接库:
go build -ldflags "-s -w" -o main.dll -buildmode=c-shared main.gomain.dll 文件 复制到 CsharpAot 项目中 , 将 Start 函数引用改成:
[LibraryImport("main.dll", SetLastError = true)][return: MarshalAs(UnmanagedType.I4)]internal static partial Int32 Start(int a, int b);
.NET 7 AOT 的使用以及 .NET 与 Go 互相调用

文章插图
执行代码调用 Start 函数:
static void Main(){var result = Native.Start(1, 2);Console.WriteLine($"1 + 2 = {result}");Console.ReadKey();}
.NET 7 AOT 的使用以及 .NET 与 Go 互相调用

文章插图
Golang 调用 C#将 CsharpExport.dll 文件复制放到 Go 项目中 。
main 的代码改成:
func main() { maindll := syscall.NewLazyDLL("CsharpExport.dll") start := maindll.NewProc("Add") var a uintptr = uintptr(1) var b uintptr = uintptr(2) result, _, _ := start.Call(a, b) fmt.Println(result)}
.NET 7 AOT 的使用以及 .NET 与 Go 互相调用

文章插图
将参数改成 19 , 再次执行:
.NET 7 AOT 的使用以及 .NET 与 Go 互相调用

文章插图
其他在本文中 , 笔者演示了 .NET AOT , 虽然简单的示例看起来是正常的 , 体积也足够小 , 但是如果加入了实际业务中需要的代码 , 最终生成的 AOT 文件也是很大的 。
例如 , 项目中使用 HttpClient 这个库 , 会发现里面加入了大量的依赖文件 , 导致生成的 AOT 文件很大 。
在 .NET 的库中 , 很多时候设计了大量的重载 , 同一个代码有好几个变种方式 , 以及函数的调用链太长 , 这样会让生成的 AOT 文件变得比较臃肿 。
目前来说 ,  ASP.NET Core 还不支持 AOT , 这也是一个问题 。
在 C# 部分 , 演示了如果使用 C# 调用系统接口 , 这里读者可以了解一下 pinvoke:http://pinvoke.net/
这个库封装好了系统接口 , 开发者不需要自己撸一遍 , 通过这个库可以很轻松地调用系统接口 , 例如笔者最近在写 MAUI 项目 , 通过 Win32 API 控制桌面窗口 , 里面就使用到 pinvoke 简化了大量代码 。
本文是笔者熬夜写的 , 比较赶 , 限于水平 , 文中可能会有错误的地方 , 望大佬不吝指教 。
【.NET 7 AOT 的使用以及 .NET 与 Go 互相调用】

经验总结扩展阅读