从C#到VC ++的编组结构数组

时间:2014-12-11 08:32:01

标签: c# c++ pinvoke marshalling

我正在尝试将一系列结构从C#编组到VC ++。

C ++函数如下所示:

void myFunc(tFileListEntry* fileList);

tFileListEntry定义为:

typedef struct FILE_LIST
{
    uint16_t FileGroupCounter;
    uint32_t FileID;
    uint16_t NumbSamples;
} tFileListEntry;

在C#中我声明了这样的函数:

[DllImport("MyLib", EntryPoint = "myFunc", CallingConvention = CallingConvention.Cdecl)]
public static extern void myFunc( [In, MarshalAs(UnmanagedType.LPArray)] tFileListEntry[] fileList);

tFileListEntry定义为:

[StructLayout(LayoutKind.Sequential)]
public class tFileListEntry
{
    public tFileListEntry(UInt16 fileGroupCounter, UInt32 fileId, UInt16 numbSamples)
    {
        FileGroupCounter = fileGroupCounter;
        FileID = fileId;
        NumbSamples = numbSamples;
    }

    public UInt16 FileGroupCounter;
    public UInt32 FileID;
    public UInt16 NumbSamples;
}

我可以在C#代码和C ++库中设置断点。在管理方面,值看起来正确,但在非管理方面,我只得到垃圾。

我使用Marshal.SizeOf()(在C#中)和sizeof()(在C ++中)验证结构的大小是两边的12个字节,所以我不认为填充/打包是一个问题在这里。

我做错了什么?

2 个答案:

答案 0 :(得分:4)

我认为这里的问题是在C#方面你已经将它声明为一个类,而不是一个结构体。

这意味着当你在C#端创建数组时,数组的每个元素都是一个引用(4或8个字节,具体取决于结构)而不是结构(12个字节),以及你看到的结果。

尝试将C#类更改为struct。

答案 1 :(得分:0)

看起来问题是我在C#端将tFileListEntry定义为class。当我将其更改为struct时,一切正常。

有趣的是,我在同一个库中有另一个C ++函数,它接受一个struct(不是一个数组),我可以成功编组一个C#class(带MarshalAs(UnmanagedType.LPStruct))。< / p>