C# 结合 Golang 开发

1. 实现方式与语法形式

基本方式:将 Go 程序编译成 DLL 供 C# 调用。

1.1 Go代码

注意:代码中 export 的注释是定义的入口描述不能省略

package main

import "C"
import "fmt"

func main() {
fmt.Println(Test())
}

var _count = 0

//Test :
//export Test
func Test() int {
_count++
return _count
}

在 LiteIDE 中将编译配置的 BUILDARGS 自定义值为 --buildmode=c-shared -o Test.dll,从而形成以下编译语句。

go build --buildmode=c-shared -o Test.dll

1.2 C# 代码

[DllImport("Test.dll", EntryPoint = "Test")]
extern static int Test();

2. Windows 下编译依赖的环境

生成 DLL 依赖于 gcc,没有 gcc 环境时,会报以下错误:

"gcc": executable file not found in %PATH%

GCC下载:Windows 64位版本  || Windows 32位版本,也可以从从云盘下载。
下载之后,解压后确保 gcc 命令在搜索路径(Path)中。
更多信息可参考:https://www.cnblogs.com/ghj1976/p/3540257.html

3. 操作系统 64 位与 32 的编译

在 LiteIDE 中,可以通过配置 win32.env 和 win64.env 来指定不同的 gcc 环境路径达到生成指定系统的 DLL 文件。

4. c# 中操作系统 64 位与 32 的适配

在 c# 中判断操作系统是否 64 位,可以使用以下语句。

bool is64 = Environment.Is64BitOperatingSystem;

为了在不同的操作系统下,加载不同的 DLL,采取以下步骤来进行组织。
(1)将 32 位的版本命名为 Test32.dll,将 64 位的版本命名为 Test64.dll
(2)定义 ITest 接口,将 DLL 将要调用的方法定义为接口方法
(3)分别为ITest接口实现 Test32 与 Test64 类,在类中加载相应的 DLL
(4)通过判断操作系统类型,实例化一个 ITest 的具体实现类实例来使用
具体接口与类实现代码如下:

public interface ITest
{
int Test();
}

public class Test32 : ITest
{
class TestDLL
{
const string DLL_NAME = "Test32.dll";

[DllImport(DLL_NAME, EntryPoint = "Test")]
public extern static int Test();
}

public int Test()
{
return TestDLL.Test();
}
}

public class Test64 : ITest
{
class TestDLL
{
const string DLL_NAME = "Test64.dll";

[DllImport(DLL_NAME, EntryPoint = "Test")]
public extern static int Test();
}

public int Test()
{
return TestDLL.Test();
}
}

实例化与调用:

ITest test = Environment.Is64BitOperatingSystem ? (ITest)new Test64() : (ITest)new Test32();
int result = test.Test();

5. 其它一些问题

5.1 字符串转换

  • 传入字符串,C#: byte[] -> GO: *C.char

  • 接收字符串,GO: string -> C#: GoString struct
    GO 定义示例

//Hello :
//export Hello
func Hello(name *C.char) string {
return fmt.Sprintf("hello %s", C.GoString(name))
}

C# GoString struct 定义

public struct GoString
{
public IntPtr p;
public int n;
public GoString(IntPtr n1, int n2)
{
p = n1; n = n2;
}
}

C# DllImport 声明

[DllImport(DLL_NAME, EntryPoint = "Hello", CallingConvention = CallingConvention.Cdecl)]
public extern static GoString Hello(byte[] name);

C# GoString struct 转 String

public string GoStringToCSharpString(GoString goString)
{
byte[] bytes = new byte[goString.n];
for (int i = 0; i < goString.n; i++)
{
bytes[i] = Marshal.ReadByte(goString.p, i);
}
string result = Encoding.UTF8.GetString(bytes);
return result;
}

C# 调用示例

GoString goResult = test.Hello(Encoding.UTF8.GetBytes("张三"));
Debug.WriteLine(GoStringToCSharpString(goResult));

5.2 调试

CallingConvention
在声明中加入 CallingConvention = CallingConvention.Cdecl 避免未知异常。

[DllImport("Test.dll", CallingConvention = CallingConvention.Cdecl)]

程序崩溃甚至异常提示都没有,可在加载 DLL 之前:

Environment.SetEnvironmentVariable("GODEBUG", "cgocheck=0");

6. 相关参考

  • GO 生成 DLL,C# 调用的一个完整小示例:
    https://github.com/Baozisoftware/go-dll

  • 字符串处理相关的一个问答
    https://stackoverflow.com/questions/48208098/using-generated-golang-dll-to-return-string-or-c-char

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

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

相关文章

Java和C++区别

Java和C的区别有很多&#xff0c;主要集中在如下几个方面&#xff1a; 运行机制 Java&#xff1a; 编写&#xff1a;是指在Java开发环境&#xff08;Eclipse、Sublime等&#xff09;中进行程序代码的输入&#xff0c;最终形成后缀名为.java的Java源文件。 编译&#xff1a;是指…

未雨绸缪 | 一文简介 Azure Front Door

点击上方蓝字关注“汪宇杰博客”导语昨天早晨微软服务器发生了核爆&#xff0c;Office 365&#xff0c;Bing&#xff0c;Azure DevOps全线完蛋。人类文明危在旦夕之际&#xff0c;微软美国的死士凌晨2点爬起来收福报&#xff0c;修好了服务器&#xff0c;拯救了全人类&#xff…

Linux下管理员权限获取(su和sudo的区别)

我们知道&#xff0c;在Linux下对很多文件进行修改都需要有root&#xff08;管理员&#xff09;权限&#xff0c;比如对/ect/profile等文件的修改。很多情况下&#xff0c;我们在进行开发的时候都是使用普通用户进行登录的&#xff0c;尤其在进行一些环境变量的配置工作时&…

左手专注,右手时间

大家好&#xff0c;我是Z哥。今天带来的是一篇有感而发的随笔&#xff0c;敬请品尝&#xff5e;前两天最火的事情莫过于WPS上市了。这个平时默默无闻、低调的可怕的产品一下子被捧上了天。我第一次接触到WPS还比较晚&#xff0c;大约在2014年的样子&#xff0c;当时由于某些特殊…

Linux下Java环境变量配置

在Java开发中&#xff0c;在安装完jdk之后&#xff0c;首先需要做的工作就是进行Java环境变量配置。在Windows下的配置我们都比较熟悉&#xff0c;图形化界面配置起来也相对容易&#xff08;详见&#xff1a;Windows7下环境变量配置&#xff09;&#xff0c;接下来我们就来了解…

说说开源那些事儿

“ 阅读本文大概需要 9 分钟。 ”前段时间我们遇到了一个情况&#xff0c;课程推送发出来之后有位同学在群里提到&#xff0c;机构提供的项目就是他同学导师的开源项目。之后这位导师在文章评论里联系了我&#xff0c;表示该机构课程涉嫌开源侵权他的 GitHub 开源项目。我们后台…

Linux下Tomcat安装和配置

1、前提&#xff08;JDK环境&#xff09;Tomcat的安装需要JDK环境&#xff0c;如何配置JDK环境见我的文章Linux下Java环境配置&#xff0c;所以在安装Tomcat之前需要先检测JDK环境是否配置好。 进入命令行界面&#xff0c;输入java -version命令来查看JDK环境是否配置成功&…

ASP.NET Core快速入门(第1章:介绍与引入)--学习笔记

点击蓝字关注我们课程链接&#xff1a;http://video.jessetalk.cn/course/explore良心课程&#xff0c;大家一起来学习哈&#xff01;任务1&#xff1a;课程介绍1、介绍与引入2、配置管理3、依赖注入4、ASP.NET Core HTTP介绍5、认证与授权6、ASP.NET Core MVC任务2&#xff1a…

Eclipse下Tomcat服务器配置和使用

在安装完Tomcat之后&#xff0c;在没有进行相关配置时&#xff0c;我们需要到终端下面去启动Tomcat。如果我们在使用Eclipse进行Java开发时&#xff0c;如果能够直接启动Tomcat服务器那将是极为方便&#xff0c;本篇就来讲述Eclipse下Tomcat服务器如何配置以及如何使用。 1、配…

Facebook押注VS Code

Facebook 近日宣布默认采用 VS Code 作为内部开发环境。去年 Facebook 宣布停止维护其开源的 Nuclide/Atom-IDE&#xff0c;以及相关的一些库。Nuclide/Atom-IDE 是 Atom 编辑器的功能包&#xff0c;其通过语言服务器协议与自定义语言服务器交互&#xff0c;为 Atom 提供一系列…

Linux下软件安装和卸载

在Windows下&#xff0c;我们安装软件基本上是先到网上下载软件的安装包&#xff0c;通常是以.exe和.msi为后缀的文件&#xff0c;然后双击安装包&#xff0c;之后就可以按照软件安装向导一步步进行安装了&#xff0c;但在Linux下&#xff0c;软件的安装方式截然不同。总的来说…

为WPF, UWP 及 Xamarin实现一个简单的消息组件

友情提示&#xff1a;阅读本文大概需要8分钟。欢迎大家点击上方公众号链接关注我&#xff0c;了解新西兰码农生活本文目录&#xff1a;1. 介绍2. Message - 消息3. Subscription - 订阅4. MessageHub - 消息总线4.1 Subscribe - 订阅4.2 Unsubscribe - 取消订阅4.3 Publish - 发…

Mac(OS X)安装、配置并使用MySQL数据库

1、MySQL安装包下载 MySQL Community Server下载地址&#xff1a;http://dev.mysql.com/downloads/mysql/&#xff0c;下载完毕之后安装文件如下所示&#xff1a; 2、MySQL安装 双击安装文件进行安装&#xff0c;出现如下界面&#xff1a; 双击窗体中的“mysql-5.7.10-osx10.9-…

用ASP.NETCore构建可检测的高可用服务

一、前言2019 中国 .NET 开发者峰会&#xff08;.NET Conf China 2019&#xff09;于2019年11月10日完美谢幕&#xff0c;校宝在线作为星牌赞助给予了峰会大力支持&#xff0c;我和项斌等一行十位同事以讲师、志愿者的身份公司参与到峰会的支持工作中&#xff0c;我自己很荣幸能…

Mac(OS X)使用brew安装软件

在Linux下&#xff0c;常用的软件包管理工具有RedHat系的yum和Debian系的apk-get&#xff0c;对于Mac的OS X系统来说&#xff0c;同样有这样的形式的软件包管理工具&#xff0c;即&#xff1a;brew。 brew 又叫Homebrew&#xff0c;是Mac OSX上的软件包管理工具&#xff0c;能…

SonarQube系列二、分析dotnet core/C#代码

来源&#xff1a;https://www.cnblogs.com/7tiny/p/11342902.html【前言】本系列主要讲述sonarqube的安装部署以及如何集成jenkins自动化分析.netcore项目。目录如下&#xff1a;SonarQube系列一、Linux安装与部署SonarQube系列二、分析dotnet core/C#代码SonarQube系列三、如何…

Eclipse使用Maven插件创建Web项目时出错:Could not resolve archetype org.apache.maven.archetypes

问题描述&#xff1a; 在Eclipse下&#xff0c;使用Maven插件创建Web项目时出错&#xff0c;错误提示如下&#xff1a; 错误信息&#xff1a; Could not resolve archetype org.apache.maven.archetypes:maven-archetype-webapp:1.0 from any of the configured repositories. …

ASP.NET Core快速入门(第2章:配置管理)--学习笔记

点击蓝字关注我们课程链接&#xff1a;http://video.jessetalk.cn/course/explore良心课程&#xff0c;大家一起来学习哈&#xff01;任务9&#xff1a;配置介绍命令行配置Json文件配置从配置文件文本到c#对象实例的映射 - Options 与 Bind配置文件热更新框架设计&#xff1a;C…

Linux下解压缩命令

在Linux下&#xff0c;很多时候我们需要对文件进行解压缩操作。尤其是在获取软件源码或安装包时&#xff0c;常常需要对文件进行解压操作。和Windows不同&#xff0c;Linux下的压缩文件形式更多、更复杂&#xff0c;操作方式往往以命令的形式进行。在此&#xff0c;对Linux下解…

怎么写技术简历?

作者&#xff1a;zollty&#xff0c;资深程序员和架构师&#xff0c;私底下是个爱折腾的技术极客&#xff0c;架构师社区合伙人&#xff01;纯手打&#xff0c;个人多年经验总结。&#xff08;本人的简历&#xff0c;历年来效果都不错&#xff0c;从校招到高端技术岗位、大厂技…