.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 互相调用】

推荐阅读