Go 程序编译成 DLL 供 C# 调用。
Go 程序编译成 DLL 供 C# 调用。
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
Go 程序编译成 DLL 供 C# 调用。的更多相关文章
- Matlab函数编译成dll供c调用
一 编译dll 在Command Window窗口中输入mbuild -setup,然后会出现语句,是否安装编译器,选择n,因为机子上已经安装了C/C++/C#的编译器,选择VS2010.
- 用IKVMC将jar转成dll供c#调用
用IKVMC将jar转成dll供c#调用 ikvmc c# dll jar 用IKVMC将jar转成dll供c#调用 前言 ikvmc介绍 ikvmc下载安装 下载并解压 设置环境变量 jar-> ...
- (二)一个工作任务引起的乱战——C++程序编译为dll,让C#调用
C++程序编译为C#可调用的dll的过程: 1.新建一个Win32 Console Application 项目,项目名为:DLLDemo,下一步选择Application type为DLL; 2.在 ...
- C#.NET常见问题(FAQ)-如何将cs文件编译成dll文件 exe文件 如何调用dll文件
比如我要把TestDLL.cs文件编译成dll文件,则在命令提示符下,输入下面的命令,生成的文件为TestDLL.dll csc /target:library TestDLL.cs 注意前提是你安装 ...
- C#.NET如何将cs文件编译成dll文件 exe文件 如何调用dll文件
比如我要把TestDLL.cs文件编译成dll文件,则在命令提示符下,输入下面的命令,生成的文件为TestDLL.dll csc /target:library TestDLL.cs 注意前提是你安装 ...
- Golang调用windows下的dll动态库中的函数 Golang 编译成 DLL 文件
Golang调用windows下的dll动态库中的函数 package main import ( "fmt" "syscall" "time&quo ...
- asp.net源程序编译为dll文件并调用的实现过程
很多时候,我们需要将.cs文件单独编译成.dll文件,这就需要使用csc命令将.cs文件编译成.dll动态链接库文件.具体的操作步骤如下: 打开命令窗口->输入cmd到控制台->cd C: ...
- Golang 编译成 DLL 文件
golang 编译 dll 过程中需要用到 gcc,所以先安装 MinGW. windows 64 位系统应下载 MinGW 的 64 位版本: https://sourceforge.net/pro ...
- 关于.Net中Process的使用方法和各种用途汇总(二):用Process启动cmd.exe完成将cs编译成dll
上一章博客我为大家介绍了Process类的所有基本使用方法,这一章博客我来为大家做一个小扩展,来熟悉一下Process类的实际使用,废话不多说我们开始演示. 先看看我们的软件要设计成的布局吧. 首先我 ...
随机推荐
- 前端笔记之React(一)初识React&组件&JSX语法
一.React项目起步配置 官网:https://reactjs.org/ 文档:https://reactjs.org/docs/hello-world.html 中文:http://react.c ...
- Bootstrap --------- 了解与使用
Bootstrap是用来做什么的?有几大部分?谁开发的?有什么特点? 一个用于快速开发 Web 应用程序和网站的前端框架. 基于 HTML.CSS.JAVASCRIPT 的. 2011 年八月在 Gi ...
- CodeForces 200D Programming Language
Recently, Valery have come across an entirely new programming language. Most of all the language att ...
- C#操作SQLite数据库增、删、改、查 欢迎转载
C#操作SQLite数据库增.删.改.查 欢迎转载 转载记得留下链接地址哦!!! 最近项目上要使用SQLite数据库,不怕大伙笑话毕业四年多了,一直使用Oracle或者MySQL或者SQLServer ...
- 创建Npm脚手架
1工具 l Npm ( https://nodejs.org/en/ ) l Yeoman (npm install -g yo) l generator-generator (npm inst ...
- 强大的Charles的使用,强大的flutter1.9
<a href="http://www.cocoachina.com/articles/37551?filter=ios"> 强大的Charles 强大的flutter
- swif(六)swift闭包
// // main.swift // LessonSwiftSix // // Created by keyan on 15/9/13. // Copyright (c) 2015年 keyan. ...
- Object-C一日速成——环境搭建
要我说,想要学习一门语言,搭建好相关的环境可以达到事半功倍的效果,那么今天我们就来聊一聊关于在windows系统上搭建Object-C语言编程环境的那些事. 文章目录 一.基于CodeBlocks的O ...
- [20191011]bash任意进制编码表.txt
[20191011]bash任意进制编码表.txt --//bash可以使用任意进制编码转化为十进制.我想了解内部编码:--//实际上受字符集的限制,"任意"进制有限制的.测试看看 ...
- [20190531]ORA-600 kokasgi1故障模拟与恢复.txt
[20190531]ORA-600 kokasgi1故障模拟与恢复.txt --//昨天看链接:http://www.xifenfei.com/2019/05/ora-600-kokasgi1-rec ...