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.envwin64.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. 相关参考

C# 结合 Golang 开发的更多相关文章

  1. 使用golang 开发的 andriod应用

    最近在捣鼓一个东东,就是使用golang开发andriod应用.说起来简单操作起来还挺麻烦,中间又学习了很多东西.比如ubuntu,docker,angular,ionic,jquery mobile ...

  2. golang开发android环境搭建_window

    golang开发android环境搭建介绍 一 安装依赖软件: git:版本管理 go:  go开发环境(版本>=1.5),可直接下载window版的go安装包. android studio: ...

  3. Windows下visual studio code搭建golang开发环境

    Windows下visual studio code搭建golang开发环境 序幕 其实环境搭建没什么难的,但是遇到一些问题,主要是有些网站资源访问不了(如:golang.org),导致一些包无法安装 ...

  4. linux golang开发环境配置(离线方式)

    <获取开发工具>     到https://www.golangtc.com/download 下载安装包, 根据自己的系统选择合适的开发包,这里选择go.1.9.2.linux-amd6 ...

  5. miniblink+golang开发windows gui应用

    golang的优点自不必说了,这么好的语言怎么能缺少界面库呢?所以我使用miniblink开发了一个可以用html,css,js开发界面的浏览器,通过它你能为你的golang开发简单的界面.说白了其实 ...

  6. Linux下golang开发环境搭建

    对于golang开发来说,Windows下可以用vscode或者liteide都不错,但是Linux下的开发也就只有vim了,所以怎么搞笑的利用vim进行golang开发呢? 参考官方推荐的一个插件: ...

  7. window / Linux 下 Golang 开发环境的配置

    一直专注于使用python语言进行程序开发,但是却又一直被它的性能问题所困扰,直到遇到了天生支持高并发的Golang,这似乎也成了学习go语言最理所当然的理由.下面介绍下Go语言开发环境搭建的步骤: ...

  8. Golang开发环境搭建-Vim篇

    一.一个干净的环境 找个干净的基础环境,方便确认每个搭建步骤后的效果: Ubuntu 14.04 x86_64 vim version 7.4.52 go version go1.4beta1 lin ...

  9. Golang开发支持平滑升级(优雅重启)的HTTP服务

    Golang开发支持平滑升级(优雅重启)的HTTP服务 - tabalt的博客 http://tabalt.net/blog/graceful-http-server-for-golang/ http ...

  10. Visual Studio Code配置GoLang开发环境

    Visual Studio Code配置GoLang开发环境 在Visual Studio Code配置GoLang开发环境 作者:chszs,未经博主允许不得转载.经许可的转载需注明作者和博客主页: ...

随机推荐

  1. web性能优化实践

    一.SQL查询优化 1.循环中有多次查询sql,改为在循环外一次查询后再处理 2.循环多次插入,改为组装好数据后批量插入 3.梳理业务逻辑能一次查完的,绝不分多次查 4.索引用起来 5.分页查询 二. ...

  2. 松软科技课堂:Winform之TextBox

    松软科技文(www.sysoft.net.cn): 文本框的几种模式:Multiline(多行).PasswordChar(密码)将文本框的PasswordChar设为*就是密码框效果,将MultiL ...

  3. 多线程——Callable接口

    package pers.aaa.callable; import java.util.concurrent.Callable; public class MyCallable implements ...

  4. java语言的开发环境

    1.Java  EE和Java  SE Java SE(Java  Platform Standard Edition)标准版:是在java基础阶段主要学习的内容,该技术是java的最核心技术,适合小 ...

  5. Day 1总结

  6. 48 (OC)* 适配iPad和iPhone、以及横竖屏适配。

    一:核心方法 1.三个方法 1.1:开始就会触发 - (void)viewWillLayoutSubviews; 1.2:开始就会触发 - (void)viewDidLayoutSubviews; 1 ...

  7. 在64系统里执行32位程序出现/lib/ld-linux.so.2: bad ELF interpreter: No such file or directory

    安装下glic即可 sudo yum install glibc.i686

  8. thymeleaf自定义标签方言处理

    项目背景:springboot+thymeleaf thymeleaf两种方式处理自定义标签:AbstractAttributeTagProcessor 和 AbstractElementTagPro ...

  9. Centos7 快速安装Docker

    写在前面 Docker是一个开源的引擎,可以轻松的为任何应用创建一个轻量级的.可移植的.自给自足的容器.开发者在笔记本上编译测试通过的容器可以轻松批量地在生产环境中部署. 网上的安装教程也很多这里我推 ...

  10. Flume初见与实践

    Photo by Janke Laskowski on Unsplash 参考书籍:<Flume构建高可用.可扩展的海量日志采集系统> --Hari Shreedharan 著 以下简称& ...