从C#调用Golang导出函数时如何处理数组参数
从C#调用Golang导出函数时如何处理数组参数 我正在尝试从C#调用一个Go函数并传入一个数组。然而,我很难让被调用的Go函数将其识别为数组。
在Go中
package main
import “C”
func main() {
}
//export DoInt
func DoInt(dataX []int) int {
return len(dataX)
}
在C#中,我这样导入
[DllImport(@“test.dll”, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
public static extern int DoInt(int[] dataX);
并在一个函数中调用它
int[] bvals = { 1, 6, 8888, 4343, 3};
int k = GoFunctions.DoInt(bvals);
在C#中,当我执行代码时,k的值是8888,而在Go函数内部,当我尝试访问dataX[0]时,我无法访问数组元素,并且代码会退出。
我应该传递一个指针吗?还是应该传递数组的引用而不是数组本身?
谢谢
更多关于从C#调用Golang导出函数时如何处理数组参数的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于从C#调用Golang导出函数时如何处理数组参数的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在Go中导出函数给C使用时,数组参数需要特殊处理。Go的切片类型([]int)在C中无法直接识别,需要转换为C兼容的类型。以下是正确的实现方式:
修改Go代码
package main
import "C"
import "unsafe"
//export DoInt
func DoInt(dataX *C.int, length C.int) C.int {
// 将C数组转换为Go切片
dataSlice := (*[1 << 30]C.int)(unsafe.Pointer(dataX))[:length:length]
// 如果需要处理为int类型
var sum C.int = 0
for i := 0; i < int(length); i++ {
sum += dataSlice[i]
}
return sum
// 或者返回长度
// return length
}
func main() {
// 空main函数,仅用于编译
}
修改C#代码
using System;
using System.Runtime.InteropServices;
public class GoFunctions
{
[DllImport(@"test.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int DoInt(IntPtr dataX, int length);
public static int CallDoInt(int[] data)
{
// 分配非托管内存
IntPtr ptr = Marshal.AllocHGlobal(data.Length * sizeof(int));
try
{
// 复制数组到非托管内存
Marshal.Copy(data, 0, ptr, data.Length);
// 调用Go函数
return DoInt(ptr, data.Length);
}
finally
{
// 释放内存
Marshal.FreeHGlobal(ptr);
}
}
}
// 使用示例
class Program
{
static void Main()
{
int[] bvals = { 1, 6, 8888, 4343, 3 };
int result = GoFunctions.CallDoInt(bvals);
Console.WriteLine($"Result: {result}");
}
}
编译Go代码
go build -buildmode=c-shared -o test.dll main.go
关键点说明
- 参数类型转换:Go的
[]int需要分解为C兼容的*C.int指针和C.int长度 - 调用约定:使用
CallingConvention.Cdecl而不是StdCall - 内存管理:C#端需要手动分配和释放非托管内存
- 类型安全:在Go中使用
unsafe.Pointer进行类型转换时需要确保边界安全
这样修改后,Go函数就能正确接收C#传递的数组参数了。

