我在C ++中有以下结构:
#define MAXCHARS 15
typedef struct
{
char data[MAXCHARS];
int prob[MAXCHARS];
} LPRData;
我正在调用一个函数来获取这些结构中的3个数组:
void GetData(LPRData *data);
在C ++中我会做这样的事情:
LPRData *Results;
Results = (LPRData *)malloc(MAXRESULTS*sizeof(LPRData));
GetData( Results );
它会工作得很好,但在C#中我似乎无法让它工作。 我已经创建了一个像这样的C#结构:
public struct LPRData
{
/// char[15]
[MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 15)]
public string data;
/// int[15]
[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 15)]
public int[] prob;
}
如果我初始化其中3个(及其所有子数组)的数组并将其传递给它:
GetData(LPRData[] data);
它成功返回,但LPRData数组中的数据没有改变。
我甚至尝试创建一个大小为3 LPRData的原始字节数组,并将其传递给这样的函数原型:
GetData(byte [] data);
但在这种情况下,我将从第一个LPRData结构中获取“data”字符串,但不会在其后面,包括来自同一LPRData的“prob”数组。
有关如何正确处理此事的任何想法?
答案 0 :(得分:25)
我会尝试为你的struct decloration添加一些属性
[StructLayout(LayoutKind.Sequential, Size=TotalBytesInStruct),Serializable]
public struct LPRData
{
/// char[15]
[MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 15)]
public string data;
/// int[15]
[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 15)]
public int[] prob;
}
*注意TotalBytesInStruct不代表变量
JaredPar也是正确的,使用IntPtr类可能会有所帮助,但是因为我使用了PInvoke所以我已经很久了。所以我生锈了。
答案 1 :(得分:13)
处理指针时的一个技巧就是使用IntPtr。然后,您可以在指针上使用Marshal.PtrToStructure,并根据结构的大小递增以获得结果。
static extern void GetData([Out] out IntPtr ptr);
LPRData[] GetData()
{
IntPtr value;
LPRData[] array = new LPRData[3];
GetData(out value);
for (int i = 0; i < array.Length; i++)
{
array[i] = Marshal.PtrToStructure(value, typeof(LPRData));
value += Marshal.SizeOf(typeof(LPRData));
}
return array;
}
答案 2 :(得分:3)
PInvoke Interop助手可能会有所帮助。 http://clrinterop.codeplex.com/releases/view/14120
答案 3 :(得分:2)
您是否使用OutAttribute标记了GetData参数?
结合InAttribute和 OutAttribute特别有用 当应用于数组并格式化时, 不易受伤的类型。来电者看到了 将被调用者更改为这些类型 仅当您应用这两个属性时。
答案 4 :(得分:2)
在this question上讨论了类似的主题,其中一个结论是CharSet
命名参数必须设置为CharSet.Ansi
。否则,我们将生成wchar_t
数组而不是char
数组。因此,正确的代码如下:
[Serializable]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct LPRData
{
[MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 15)]
public string data;
[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 15)]
public int[] prob;
}