日期:2014-05-17  浏览次数:21039 次

请教Marshal的问题
本帖最后由 just_swizard 于 2013-10-18 11:51:17 编辑
本人一直做C++,最近因为项目需要开始接触C#,遇到一些问题,特来请教各位大牛

项目需要用C#调用C++的dll,接口形如
int func(A* a, B* b, C* c);
A,B,C都是自定义的结构体,B、C比较简单,关键在于A

struct A
{
unsigned char** data[4];
long* pHeight;
...// 一些简单类型(long,short)变量
short reserved[2];
}


我的C#侧定义的结构体A:

[StructLayout(LayoutKind.Sequential)]
struct A
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public IntPtr[] data;
[MarshalAs(UnmanagedType.LPArray)]
public int[] pHeight;
...//一些简单变量,long-->int,short-->short
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public short[] reserved;
}


出错信息:
Cannot marshal field 'data' of type 'A': Invalid managed/unmanaged type combination  (Arrays fields must be paired with ByValArray or SafeArray).

是IntPtr[]这里写法有问题么,是的话要怎么写才对呢,谢谢了。

------解决方案--------------------
public IntPtr[] data 对应的是行指针(指向数组的指针)
unsigned char** data[4]是一个二级指针,一级指针的类型是unsigned char[4]

指定ArraySubType试试,U4是4字节无符号整数
[MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.U4)]
------解决方案--------------------
引用:
...
是IntPtr[]这里写法有问题么,是的话要怎么写才对呢,谢谢了。


IntPtr[] Data;倒是没有问题。错误信息很清楚的说了:
“Arrays fields must be paired with ByValArray or SafeArray”。因此:
public int[] pHeight;有问题。

可以改成下列签名(不过你要自己准备那个pHeight):
[StructLayout(LayoutKind.Sequential)]
struct A
{
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
    public IntPtr[] data;
    public IntPtr pHeight;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
    public short[] reserved;
}