【C# 调用 Go 语言】0x2 参数、返回值与类型转换

在上篇文章【C# 调用 Go 语言】0x1 Hello Golang  中,我们将 Golang 源码编译为动态链接库(dll),用 C# 调用 Golang 导出的方法并成功的看到了控制台的输出。本篇文章将对 C# 调用 Golang 方法做更详细的介绍,涉及如何对 Golang 方法进行传参、获取返回值以及处理调用过程中的类型转换。

本文源代码可以在  https://gitee.com/coderbusy/golang-with-csharp 找到。

基本的传参与返回值

使用 Golang 编写一个名为 Check 的方法,该方法接收两个整型的参数(i1,i2)并返回一个布尔值,当 i1 > i2 时返回值为 True,否则为 False :

需要一个 make.bat 文件,用于生成动态链接库:

同上篇,将 C# 项目 Golang.Ioc 的目标平台设置为 x86 ,将生成的 Golang.Ioc.Interop.dll 复制到项目中并设置为始终复制:

使用 P/Invoke 调用导出的方法:

运行之后,程序将会产生如下输出,程序行为符合我们的预期:

C、CGO、Golang 与 P/Invoke

C/C++ 经过几十年的发展,已经积累了庞大的软件资产,它们很多久经考验而且性能已经足够优化。Go 语言必须能够站在 C/C++ 这个巨人的肩膀之上,有了海量的 C/C++ 软件资产兜底之后,我们才可以放心愉快地用 Go 语言编程。C 语言作为一个通用语言,很多库会选择提供一个 C 兼容的 API,然后用其他不同的编程语言实现。Go 语言通过自带的一个叫 CGO 的工具来支持 C 语言函数调用,同时我们可以用 Go 语言导出 C 动态库接口给其它语言使用。

Go语言高级编程 》 第二章 CGO编程

P/Invoke 的全称是 Platform Invoke (平台调用) 它实际上是一种函数调用机制,通过 P/Invoke 我们就可以调用非托管 DLL 中的函数。实际上很多 NET 基类库中定义的类型内部调用了从 Kernel32.dll,User32.dll,gdi32.dll 等非托管 DLL 中导出的函数。

之所以可以在 C# 中调用 Golang 程序集是因为 CGO 在中间充当了桥梁。我们的调用顺序应该是 C# -> C -> Golang 。

下表列出了 Windows API 和 C 样式函数中使用的数据类型。许多非托管库包含将这些数据类型作为参数和返回值传递的函数。第三列列出了相应的 .NET Framework 内置值类型或可在托管代码中使用的类。

Windows API 中的非托管类型非托管 C 语言类型托管类型描述
VOIDvoidSystem.Void应用于不返回值的函数。
HANDLEvoid *System.IntPtr 或 System.UIntPtr在 32 位 Windows 操作系统上为 32 位、在 64 位 Windows 操作系统上为 64 位。
BYTEunsigned charSystem.Byte8 位
SHORTshortSystem.Int1616 位
WORDunsigned shortSystem.UInt1616 位
INTintSystem.Int3232 位
UINTunsigned intSystem.UInt3232 位
LONGlongSystem.Int3232 位
BOOLlongSystem.Boolean 或 System.Int3232 位
DWORDunsigned longSystem.UInt3232 位
ULONGunsigned longSystem.UInt3232 位
CHARcharSystem.Char使用 ANSI 修饰。
WCHARwchar_tSystem.Char使用 Unicode 修饰。
LPSTRchar *System.String 或 System.Text.StringBuilder使用 ANSI 修饰。
LPCSTRconst char *System.String 或 System.Text.StringBuilder使用 ANSI 修饰。
LPWSTRwchar_t *System.String 或 System.Text.StringBuilder使用 Unicode 修饰。
LPCWSTRconst wchar_t *System.String 或 System.Text.StringBuilder使用 Unicode 修饰。
FLOATfloatSystem.Single32 位
DOUBLEdoubleSystem.Double64 位

Go语言中数值类型和C语言数据类型基本上是相似的,以下是它们的对应关系表:

C语言类型CGO类型Go语言类型
charC.charbyte
singed charC.scharint8
unsigned charC.ucharuint8
shortC.shortint16
unsigned shortC.shortuint16
intC.intint32
unsigned intC.uintuint32
longC.longint32
unsigned longC.ulonguint32
long long intC.longlongint64
unsigned long long intC.ulonglonguint64
floatC.floatfloat32
doubleC.doublefloat64
size_tC.size_tuint

需要注意的是,虽然在C语言中int、short等类型没有明确定义内存大小,但是在CGO中它们的内存大小是确定的。在CGO中,C语言的int和long类型都是对应4个字节的内存大小,size_t类型可以当作Go语言uint无符号整数类型对待。

在编写完 Golang 代码后,如果不确定对应的 C# 类型,那么可以查看在编译后与 DLL 同时生成的 .h 头文件,对应上面两张表应该就可以找到正确的类型 。

字符串类型参数

如果一个方法需要导出并且参数或返回值涉及到字符串,通常使用 *C.char 来代替 Golang 内置的 string 类型对外导出。可以调用 C.CString 方法将 Golang 的字符串类型转为 *C.char 类型:

需要注意的是:C string 在 C 的堆上使用 malloc 申请。调用者有责任在合适的时候对该字符串进行释放,释放方式可以是调用C.free(调用C.free需包含stdlib.h)。

在 Golang 源码中新增 GetSlogan 方法,该方法接受一个名为 name 的字符串参数,并返回一句为武汉加油的口号。为了可以在返回值使用完成后释放掉由 C.CString 申请的内存,再增加一个 Free 方法:

C# 提供一个 ICustomMarshaler 接口,可以用它来对托管内存和非托管内存进行转换。添加一个 CStringMarshaler  实现 ICustomMarshaler 接口,帮我们处理 C# string 和 C.CString 之间的转换过程,并保证内存被正确释放:

测试一下对 GetSlogan 方法的调用:

运行代码后将产生以下输出:

增加代码进行性能测试:

调用 52 万 1 千次后,内存占用仍在 20M 以内,可以证明没有发生内存泄漏问题:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/312081.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AcWing 1214. 波动数列

观察这个数列: 1 3 0 2 -1 1 -2 … 这个数列中后一项总是比前一项增加2或者减少3,且每一项都为整数。 栋栋对这种数列很好奇,他想知道长度为 n 和为 s 而且后一项总是比前一项增加 a 或者减少 b 的整数数列可能有多少种呢? 输入格…

单链表式并查集应用举例

给定一个长度为 N 的数组 A[A1,A2,⋅⋅⋅AN],数组中有可能有重复出现的整数。 现在小明要按以下方法将其修改为没有重复整数的数组。 小明会依次修改 A2,A3,⋅⋅⋅,AN。 当修改 Ai 时,小明会检查 Ai 是否在 A1∼Ai−1 中出现过。 如果出现过,…

《ASP.NET Core 微服务实战》-- 读书笔记(第1章 、第2章)

译者序微服务设计方法清晰定义了各个开发团队的业务边界,微服务框架以不同方式实现了服务之间的协作与集成。.NET Core 作为全新的 .NET 技术,它不仅完全开源、跨平台,更面向云原生开发进行了大量细致的优化。它完全模块化,不依赖…

html缩进标签quote,HTML blockquote 标签

HTML 标签标签同样是对文本进行引用,不同的是该标签引用的是长文本。标签内的内容会自动有缩进。实例定义一个摘自另一个源的块引用:For 50 years, WWF has been protecting the future of nature. The worlds leading conservation organization, WWF w…

大学计算机基础英语翻译,大学计算机基础 教学课件 978 7 302 21247 8 第7章 常用工具软件.pdf...

第7章 常用工具软件7.1 文件压缩工具——WinRAR7.2 图片浏览工具——ACDSee7.3 常用杀毒工具——RISING7.4 硬盘备份工具——Ghost7.5 翻译工具——金山词霸7.6 迅雷下载工具——Thunder《大学计算机基础》 第7章 常用工具软件 第1页7.1 文件压缩工具——WinRARWinRAR是32位W…

AcWing 1047. 糖果

由于在维护世界和平的事务中做出巨大贡献,Dzx被赠予糖果公司2010年5月23日当天无限量糖果免费优惠券。 在这一天,Dzx可以从糖果公司的 N 件产品中任意选择若干件带回家享用。 糖果公司的 N 件产品每件都包含数量不同的糖果。 Dzx希望他选择的产品包含的糖…

使用BeetleX.NetBenchmark压测TCP,HTTP和Websocket服务

真没想到大过年还在家里写代码写文章,本来还打算自驾半个月没想出现这情况。在这里祝福全国同胞在新的一年里身体健康!希望阳光天气早日照射在这片土地上,给人带来新一年的希望!NetBenchmark是针对网络服务压测的开源组件&#xf…

HTML怎么去除数组的重复元素,js去除数组中重复元素并排序

/p>"http://www.w3.org/TR/html4/strict.dtd">003_obj//去掉数组中重复的元素var arr[1,2,2,3,3,5,5,1,2,4,7,8,96,3,5,2,1,4,5];//解析步骤//1.把数组转换成一个JS对象//2.把数组中的值变成JS对象中的Key//3.把这个对象再还原成数组//将数组转换成对象functio…

AcWing 1234. 倍数问题

众所周知,小葱同学擅长计算,尤其擅长计算一个数是否是另外一个数的倍数。 但小葱只擅长两个数的情况,当有很多个数之后就会比较苦恼。 现在小葱给了你 n 个数,希望你从这 n 个数中找到三个数,使得这三个数的和是 K 的倍…

如何使用Serilog.AspNetCore记录ASP.NET Core3.0的MVC属性

这是Serilog系列的第三篇文章。第1部分-如何利用Serilog的RequestLogging来精简ASP.NET Core的日志输出第2部分-Serilog高级玩法之用Serilog记录所选终结点附加属性第3部分-使用Serilog.AspNetCore记录MVC属性(本文)第4部分-从Serilog请求记录中排除运行…

广东省计算机媒体大赛,广东省大学生计算机设计大赛

广东省大学生计算机设计大赛由广东省教育厅主办。比赛宗旨为进一步提高广东省高校计算机教学和信息技术与学科深度融合的水平,激发省内各高校各专业大学生学习计算机知识和技能的兴趣和潜能,提升大学生运用信息技术解决实际问题的综合实践能力&#xff0…

哈希表-拉链法及应用举例

哈希表存储结构: 1.开放寻址法 2.拉链法 哈希表的主要作用: 把一个较大(0-10^9 )的数据映射到较小(0-N(N一般为10^5 到 10^6))的数据 哈希函数:可以把一个从-10^19 到10^19 的中的一个数映射到0-10^5之间的一个数 1.哈希函数怎么写&#x…

C++map容器应用举例

维护一个集合,支持如下几种操作: “I x”,插入一个数x; “Q x”,询问数x是否在集合中出现过; 现在要进行N次操作,对于每个询问操作输出对应的结果。 输入格式 第一行包含整数N,表示…

各互联网公司延期上班一览

【延期上班,自我隔离】自从1月26日,国家颁布了延长春节假期的公告之后,互联网行业各公司也纷纷更新了自己的延期上班计划,如下表所示:可以看到,多数公司采取了在家办公的这种模式,还有些公司直接…

计算机系统占有率,微软继续领跑PC操作系统市场 Win10占有率突破25%

腾讯科技讯,据外媒报道,发布一年半之后,Windows 10的市场占有率终于跨过25%这一里程碑,这就意味着,如今世界上每四台电脑中就有一台运行Windows 10系统。Net Applications的数据显示,Windows 10发布后四周内…

递推求组合数

组合数计算公式&#xff1a; 递推公式&#xff1a; 代码模板&#xff1a; #include <iostream> using namespace std; const int N 1010; int c[N][N];int main() {int a,b;cin>>a>>b;//a在下&#xff0c;b在上for (int i 0;i<N;i)for (int j 0;j&…

微软发布 Power BI 2020 上半年发行计划

微软官方与日前发布了 Power BI 在2020上半年的发行计划。本文将在 2020.9 之前都有用&#xff0c;建议收藏查看。从今年开始&#xff0c;我们除了客观描述 Power BI 的特性外&#xff0c;还将加入大量主观观点态度和吐槽&#xff0c;不过不管怎么吐&#xff0c;都只能继续用&a…

星光计划计算机,上海星光计划第七届职业院校技能大赛.PDF

上海市“星光计划”第七届职业院校技能大赛数字影视后期制作决赛方案上海市星光计划组委会竞赛办公室二○一六年十二月目 录1. 简介 11.1 项目名称 1数字影音后期制作项目 11.2 项目说明 12. 决赛内容及要求 12.1 模块一&#xff1a;音视频素材管理 12.2 模块二&#xff…

AcWing 523. 组合数问题

组合数 Cmn 表示的是从 n 个物品中选出 m 个物品的方案数。  举个例子&#xff0c;从 (1, 2, 3) 三个物品中选择两个物品可以有 (1, 2), (1, 3), (2, 3) 这三种选择方法。  根据组合数的定义&#xff0c;我们可以给出计算组合数 Cmn 的一般公式&#xff1…

远程办公经验为0,如何将日常工作平滑过度到线上?

导语 | 受到疫情影响&#xff0c;很多企业开始考虑远程办公。近日&#xff0c;TVP群里的各位老师们对此话题展开了热烈讨论。TVP张善友老师作为一名创业者&#xff0c;也决定开启远程办公。本文是他对相关经验总结而得的方案&#xff0c;并列出了相关产品清单&#xff0c;希望对…