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%

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();

还有一种方式:

[DllImport("kernel32")]

private static extern IntPtr LoadLibraryA([MarshalAs(UnmanagedType.LPStr)] string fileName);

-- DllImport 会先在加载的里边找名称,可以预先加载。

LoadLibraryA((Environment.Is64BitOperatingSystem ? "x64" : "x86") + "/Test.dll");

补充一下 LoadLibrary 的查找路径说明

LoadLibrary的查找路径,可以参见MSDN上的文章:Dynamic-Link Library Search Order。

默认情况如下:

The directory from which the application loaded. (应用程序所在的目录)

The system directory. Use the GetSystemDirectory function to get the path of this directory. (system32目录)

The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched. (System目录)

The Windows directory. Use the GetWindowsDirectory function to get the path of this directory. (Windows目录)

The current directory. (当前目录,执行命令的发起目录)

The directories that are listed in the PATH environment variable. Note that this does not include the per-application path specified by the App Paths registry key. (PATH路径)

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语言 c# 混合编程 pdf,C# 结合 Golang 开发相关推荐

  1. go语言 c# 混合编程 pdf,【C# 调用 Go 语言】0x1 Hello Golang-Go语言中文社区

    C# 和 Golang 都不是世界上最好的语言.在不同的业务场景下,C# 和 Golang 各有所长.如果要编写一个网络程序,显然 Golang 更擅长,而如果要编写一个桌面 GUI 程序,那么 C# ...

  2. extern quot;Cquot; 的含义:实现C++与C及其他语言的混合编程

    C++中extern "C"的设立动机是实现C++与C及其他语言的混合编程. C++为了支持函数的重载.C++对全局函数的处理方式与C有明显的不同. 对于函数void foo( i ...

  3. 汇编c语言混合编程pdf,C语言及汇编语言混合编程的方法.pdf

    维普资讯 1993矩 化 工 电 子 计 算 第 2期 C语言与汇编语言混合编程的方法 f/1) (南京犬李葛于如丽顶吾学系) 摘 要 本文通过实例阐述了当前较为漉行的两种c语盲 (Microsoft ...

  4. c语言混合编程 pdf,C语言与汇编语言混合编程的方法.pdf

    C语言与汇编语言混合编程的方法 维普资讯 讫 梅 龄 施 扰 绝 埔 综 勿 穗 直 触 搔 拌 橱 悬 邱 舟 絮 颈 茬 辞 乏 味 绞 涡 菊 黄 宜 悄 条 搬 悄 俱 泼 洋 醚 檀 测 易 ...

  5. 嵌入式c语言汇编混合编程,嵌入式C语言和汇编语言的混合编程

    此文章简单介绍 单片机 C语言和汇编语言混合编程的例子.主要用单片机汇编语言编写DS1302的底层驱动,在C语言里通过调用汇编语言,从而实现C和汇编的混合编程. ;汇编语言源文件 ;========= ...

  6. c语言汇编混合编程方法,C语言和汇编语言混合编程方法

    摘要: C语言是一种高级的面向过程的开发语言,汇编语言是一种低级的面向机器的编程语言.两者在程序设计开发方面各有优劣,目前两者的混合编程得到了广泛的应用.本文通过具体的实例,说明了混合编程的基本方法, ...

  7. d语言 c++ 混合编程,C++,D语言,Python语言一次模拟合作开发

    我想要做一个网络server,一个网络client. server主要就是一个echo回应,client连上服务器后打印服务器返回的回应. Python做一个性能测试,调用50000次client去连 ...

  8. c语言汇编混合编程写一个乘法,求通过C语言实现矩阵的加、减及乘法。要自己写的,不要复制过来...

    满意答案 eevfikx2 2013.11.28 采纳率:53%    等级:13 已帮助:8891人 #include using namespace std; int main() { int a ...

  9. java语言用什么编程_使用什么编程语言开发Java?

    The Java Language is a language specification – you don't write a language in a language, it's a spe ...

最新文章

  1. 厦门大学江保详:缺陷检测的讲解!
  2. 如何用法向量求点到平面距离_高中数学丨2020新标课本,空间向量与二面角所有知识点,一张表搞定...
  3. GIT:本地有更改,但强制作远程仓库里作更新
  4. Acwing第 13 场周赛【未完结】
  5. Python教程:内置函数filter()和匿名函数lambda解析
  6. hdfs restful API:httpfs与webhdfs的简单使用
  7. run spark pi_Spark Run本地设计模式
  8. js encodeurl java接收_在JS中encodeURI(url)怎样才能不出现乱码?
  9. Android Jenkins自动化构建之路
  10. Android7.0 emui主题,全新EMUI5.0基于Android7.0 天生快,一生快!
  11. python统计字符串中字母个数字母无视大小写_python判断字符串是字母 数字 大小写(转载)...
  12. matlab数据栅格化,新手求卫星降水数据CMORPH_V1.0数据完整处理方法,有matlab打开的代码但是不会处理...
  13. 一个初学者的辛酸路程-函数-4
  14. swiper5 点击图换下一张_软网推荐:骗倒社交好友 制作另类隐藏图
  15. 无法听到计算机发出的声音怎么办,为什么视频对方听不到我说话_电脑视频对方听不到声音的解决方法...
  16. 如何划分IP地址及范围
  17. 怎么装python的keras库_Keras 教程: Python 深度学习终极入门指南
  18. premiere pr 自动调色对比度 用法
  19. 苹果iPhone白屏死机?如何修复?
  20. Codeforces 1247D. Power Products (logn质因数分解)

热门文章

  1. java 四人帮,Java PatternDesign of GOF(四人帮巨著,享誉15年)第十五模式
  2. c语言英文星期几,输入字母,判断星期几,求大神指点
  3. 输入数字存入数组C语言,//从键盘上输入若干整数,并将其存入数组中,并统计输入数据的个...
  4. android 页面整体滑动,ScrollView 实现页面整体滑动
  5. openwrt dhcp 无法获取ip_电脑的 ip 是怎么来的呢?我又没有配置过
  6. python迭代器是什么百度百科,python迭代器的接口是什么?
  7. git 提交文件_GIT不小心提交了大文件导致提交失败怎么办?
  8. python在材料方面的应用_python记录材料题带标准答案
  9. 【Python】Pygame模块设计游戏
  10. SpringBoot学习笔记2