【问题标题】:Marshalling array of struct from C# to VC++将结构数组从 C# 编组到 VC++
【发布时间】:2014-12-11 08:32:01
【问题描述】:

我正在尝试将结构数组从 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 个字节,所以我认为填充/打包在这里不是问题。

我做错了什么?

【问题讨论】:

    标签: c# c++ pinvoke marshalling


    【解决方案1】:

    我认为这里的问题是,在 C# 方面,您已将其声明为类,而不是结构。

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

    尝试将 C# 类更改为 struct。

    【讨论】:

      【解决方案2】:

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

      有趣的是,我在同一个库中有另一个 C++ 函数,它接受单个 struct(不是数组),并且我可以成功编组 C# class(使用 MarshalAs(UnmanagedType.LPStruct))。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-12-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-26
        相关资源
        最近更新 更多