1、首先下载安装mingw-w64-install.exe,安装的时候根据go的架构选择64位或i686,安装后将mingw下的bin加入到PATH环境变量,打开控制台,输入gcc,查看是否安装成功。
下载地址:https://github.com/niXman/mingw-builds-binaries/releases
x86_64-14.2.0-release-posix-seh-msvcrt-rt_v12-rev0
下载解压缩后然后再
设置入口:开始 > 设置 > 系统 > 关于 > 高级系统设置 > 环境变量
path C:\gcc\mingw64\bin
2、编写go代码:
package main
import "C"
//export ProcessStrings
func ProcessStrings(a *C.char, b *C.char) *C.char {
// 将 C 字符串转换为 Go 字符串
goStrA := C.GoString(a)
goStrB := C.GoString(b)
// 确保 Go 字符串是 UTF-8 编码(Go 字符串默认是 UTF-8 编码)
utf8StrA := []byte(goStrA)
utf8StrB := []byte(goStrB)
// 处理字符串,例如将它们连接起来
result := string(utf8StrA) + " 和 " + string(utf8StrB)
// 返回新的 UTF-8 编码字符串
return C.CString(result)
}
func main() {}
3、运行命令行编译dll:go build -buildmode=c-shared -o 生成的DLL名称.dll go源码文件名称.go go build --buildmode=c-shared -o Test.dll
3.1、排查 Build constraints exclude all the go files 的几个思路
若非操作系统环境的问题,接着考虑是否有交叉编译,即在 Go 语言编译时调用了其他语言的情况,一般是 C 语言。此时需要在 go env 中开启 CGO_ENABLED 特性。这样在进行 go build 时,就会在编译和链接阶段启动 gcc 编译器。(经评论指出,开启 CGO_ENABLED 需要下载对应操作系统的 gcc 库)go env -w CGO_ENABLED=1
来自:https://blog.csdn.net/weixin_45651194/article/details/130530209
4、确保安装的go版本支持编译动态链接库,如果版本低,会提示-buildmode=c-shared not supported on windows/amd64等错误。
5、在C#中导入并调用:
using System;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
// 声明一个外部函数来调用 Go 函数
[DllImport("exc.dll", CharSet = CharSet.Ansi)]
public static extern IntPtr ProcessStrings(byte[] a, byte[] b);
private void button1_Click(object sender, EventArgs e)
{
string zy = checkBox1.Checked ? "1" : "0";
string url = this.textBox1.Text;
string requestEncod = this.richTextBox1.Text;
// 将 C# 字符串转换为 UTF-8 编码的字节数组
byte[] utf8StrA = Encoding.UTF8.GetBytes(zy);
byte[] utf8StrB = Encoding.UTF8.GetBytes(url);
IntPtr resultPtr = ProcessStrings(utf8StrA, utf8StrB);
string result = PtrToStringUTF8(resultPtr);
Console.WriteLine("Result: " + result);
MessageBox.Show(result, "应用提示");
}
public static string PtrToStringUTF8(IntPtr ptr)
{
if (ptr == IntPtr.Zero)
return null;
int len = 0;
while (Marshal.ReadByte(ptr, len) != 0)
len++;
byte[] buffer = new byte[len];
Marshal.Copy(ptr, buffer, 0, buffer.Length);
return Encoding.UTF8.GetString(buffer);
}
private void Form1_Load(object sender, EventArgs e)
{
}
}