如何制作Int数组或指向Int数组的指针

时间:2013-08-07 12:40:32

标签: c# c arrays marshalling

(我知道这可能是重复但我不理解其他线程)

我正在使用C#,我有第三方dll需要int数组(或指向int数组的指针)作为参数。如何在C#和C / C ++之间编组int数组?函数声明如下:

// reads/writes int values from/into the array
__declspec(dllimport) void __stdcall ReadStuff(int id, int* buffer);

在C int*中指针是否正确?所以如果我必须使用IntPtr或者我可以使用int[](首选),我会感到困惑吗?我认为这可能没问题:

[DllImport(dllName)]
static extern void ReadStuff(int id, [MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_I4)] ref int[] buffer);

// call
int[] array = new int[12];
ReadStuff(1, ref array);

那会有用吗?或者我如何在安全代码中用C#声明这个函数?

2 个答案:

答案 0 :(得分:4)

它不是SafeArray。 SafeArray是与Variants相关的东西和OLE的旧时代:-)它可能存在于“dodo”这个词附近的字典中。

是:

[DllImport(dllName, CallingConvention=CallingConvention.StdCall)]
static extern void ReadStuff(int id, int[] buffer);
编组人员会做“正确”的事情。

[DllImport(dllName, CallingConvention=CallingConvention.StdCall)]
static extern void ReadStuff(int id, IntPtr buffer);

然后使用它会更复杂。

CallingConvention=CallingConvention.StdCall是默认值,因此没有必要明确写出来。

你用这种方式:

// call
int[] array = new int[12];
ReadStuff(1, array);

ref int[]将是int**(但传递可能很复杂,因为通常你接收数组,而不是发送数组:-))

请注意,您的“界面”非常差:您无法告诉ReadStuff缓冲区的长度,也无法获得必要的缓冲区长度,也无法获得真正使用的缓冲区。

答案 1 :(得分:0)

你可以这样做:

[DllImport(dllName)]
static extern void ReadStuff(int id, IntPtr buffer, int length);


int[] array = new int[12];

unsafe
{
  fixed (int* data = &array[0])
    ReadStuff(1, data, array.Length);
}

C ++代码:(未经测试)

extern "C" __declspec(dllexport) VOID WINAPI ReadStuff(int id, int* buffer, int length);