目录
- 背景
- C# 部分
- 环境要求
- 创建一个控制台项目
- 体验 AOT 编译
- C# 调用库函数
- 减少体积
- C# 导出函数
- C# 调用 C# 生成的 AOT
- Golang 部分
- 安装 GCC
- Golang 导出函数
- .NET C# 和 Golang 互调
- C# 调用 Golang
- Golang 调用 C#
- 其他
最近时总更新太快了,太卷了,所以借着 .NET 7 正式版发布,熬夜写完这篇文章,希望能够追上时总的一点距离 。
本文主要介绍如何在 .NET 和 Go 语言中如何生成系统(Windows)动态链接库,又如何从代码中引用这些库中的函数 。
在 .NET 部分,介绍如何使用AOT、减少二进制文件大小、使用最新的
[LibraryImport]
导入库函数;在 Go 语言部分,介绍如何使用 GCC 编译 Go 代码、如何通过
syscall
导入库函数 。在文章中会演示 .NET 和 Go 相互调用各自生成的动态链接库,以及对比两者之间的差异 。
本文文章内容以及源代码,可以 https://github.com/whuanle/csharp_aot_golang 中找到,如果本文可以给你带来帮助,可以到 Github 点个星星嘛 。
C# 部分环境要求SDK:.NET 7 SDK、Desktop development with C++ workload 。
IDE:Visual Studio 2022
Desktop development with C++ workload
是一个工具集,里面包含 C++ 开发工具,需要在 Visual Studio Installer
中安装,如下图红框中所示 。文章插图
创建一个控制台项目首先创建一个 .NET 7 控制台项目,名称为
CsharpAot
。打开项目之后,基本代码如图所示:
文章插图
我们使用下面的代码做测试:
public class Program{static void Main(){Console.WriteLine("C# Aot!");Console.ReadKey();}}
体验 AOT 编译这一步,可以参考官方网站的更多说明:https://learn.microsoft.com/zh-cn/dotnet/core/deploying/native-aot/
为了能够让项目发布时使用 AOT 模式,需要在项目文件中加上
<PublishAot>true</PublishAot>
选项 。文章插图
然后使用 Visual Studio 发布项目 。
发布项目的配置文件设置,需要按照下图进行配置 。
文章插图
AOT 跟配置完成后,点击生成单个文件
两个选项不能同时使用 , 因为 AOT 本身就是单个文件 。
发布
,然后打开 Release
目录 , 会看到如图所示的文件 。文章插图
.exe
是独立的可执行文件,不需要再依赖 .NET Runtime
环境,这个程序可以放到其他没有安装 .NET 环境的机器中运行 。然后删除以下三个文件:
CsharpAot.expCsharpAot.libCsharpAot.pdb
光用剩下.exe
即可运行,其他是调试符号等文件,不是必需的 。
CsharpAot.exe
文件后,启动这个程序:文章插图
C# 调用库函数这一部分的代码示例 , 是从笔者的一个开源项目中抽取出来的 , 这个项目封装了一些获取系统资源的接口,以及快速接入 Prometheus 监控 。
不过很久没有更新了,最近没啥动力更新 , 读者可以点击这里了解一下这个项目:
https://github.com/whuanle/CZGL.SystemInfo/tree/net6.0/src/CZGL.SystemInfo/Memory
因为后续代码需要,所以现在请开启 “允许不安全代码” 。
本小节的示例是通过使用
kernel32.dll
去调用 Windows 的内核 API(Win32 API) , 调用 GlobalMemoryStatusEx
函数 检索有关系统当前使用物理内存和虚拟内存的信息 。使用到的 Win32 函数可参考:https://learn.microsoft.com/zh-cn/windows/win32/api/sysinfoapi/nf-sysinfoapi-globalmemorystatusex
关于 .NET 调用动态链接库的方式,在 .NET 7 之前,通过这样调用:
[DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)][return: MarshalAs(UnmanagedType.Bool)]internal static extern Boolean GlobalMemoryStatusEx(ref MemoryStatusExE lpBuffer);
在 .NET 7 中 , 出现了新的操作方式
推荐阅读
- 我的Vue之旅 10 Gin重写后端、实现页面详情页 Mysql + Golang + Gin
- 王者荣耀古今物语怎么获取
- 王者荣耀荣耀值怎么获取
- 许褚是怎样死的(许褚最怕的三个人)
- 《火影忍者》:二代火影真正的死因是什么为什么说是不会解开的迷题
- 一个人在家该怎么玩最舒服(一个人在家很舒服的文案)
- 18岁生日怎么玩有意思(18岁生日要做的事)
- AirPods3与AirPods Pro的区别_买哪个性价比更高?
- 朋友婚礼送礼物排行:最实用且最有意义的都在这里
- 鼠标划着划着不动了怎么办(鼠标划的太快就不动了)