将具有 int* 成员的 C++ 结构编组到 C#

Posted

技术标签:

【中文标题】将具有 int* 成员的 C++ 结构编组到 C#【英文标题】:Marshalling C++ struct with a int* member to C# 【发布时间】:2014-11-26 11:17:57 【问题描述】:

我在下面有一个 C++ 结构:

struct CTMDeviceError 
    struct CTMDeviceInfo sDeviceInfo;
    int32_t              iResultCode;
    int32_t              iExtendedResultCode;
    int32_t *            piDenomination;
    int32_t *            piChangeDue;
;

我创建了一个等效的 c# 结构,但我在编组 int32 * 类型时遇到了问题。

[StructLayout(LayoutKind.Sequential)]
public struct CTMDeviceError

    public CTMDeviceInfo deviceInfo;

    [MarshalAs(UnmanagedType.I4)]
    public Int32 resultCode;

    [MarshalAs(UnmanagedType.I4)]
    public Int32 extendedResultCode;

    public ??? denomination;

    public ??? changeDue;
;

我曾尝试使用 IntPtr 或 Int32[],但 Visual Studio 显示不匹配错误。 我能得到一些建议吗? 谢谢!

这是结构体的其余细节:

c++

struct CTMDeviceInfo 
    enum CTMDeviceType eDeviceType;
    char *             szDeviceModel;
    char *             szDeviceSubModel;
    int32_t *          piDeviceID;
;

enum CTMDeviceType 
    CTM_DEVICETYPE_CASHCHANGER  = 5,
    CTM_DEVICETYPE_CASHACCEPTOR = 15,
    CTM_DEVICETYPE_COINACCEPTOR = 16,
    CTM_DEVICETYPE_OTHER        = 17
;

c#

[StructLayout(LayoutKind.Sequential)]
public struct CTMDeviceInfo

    public CTMDeviceType deviceType;

    [MarshalAs(UnmanagedType.LPStr)]
    public string deviceModel;

    [MarshalAs(UnmanagedType.LPStr)]
    public string deviceSubModel;

    public ??? deviceId;
;

public enum CTMDeviceType
    
        CTM_DEVICETYPE_CASHCHANGER = 5,
        CTM_DEVICETYPE_CASHACCEPTOR = 15,
        CTM_DEVICETYPE_COINACCEPTOR = 16,
        CTM_DEVICETYPE_OTHER = 17
    ;

【问题讨论】:

如果我使用 Intptr,exe 会崩溃并给我发送一个我不理解的长错误报告。如果我使用 [MarshalAs(UnmanagedType.I4)] public Int32[] 面额,它会给我这个 => Unknown Module 中发生类型为“System.TypeLoadException”的未处理异常。附加信息:无法编组“CTMOnCSharp.CTMDeviceError”类型的字段“deviceInfo”:该字段的类型定义具有布局信息,但托管/非托管类型组合无效或不可编组。 我尝试使用 [MarshalAs(UnmanagedType.LPArray)] public System.IntPtr changeDue 但我仍然收到不匹配错误。可能我的格式不对。 【参考方案1】:

指针的类型应该是System.IntPtr

【讨论】:

我刚试过,但没用。应用程序崩溃。 VS 给了我一个很长的错误报告,我不明白。谢谢! 您确定错误是由 IntPtr 引起的吗? deviceInfo 看起来更像是罪魁祸首。 我已经更新了描述,增加了结构的细节。

以上是关于将具有 int* 成员的 C++ 结构编组到 C#的主要内容,如果未能解决你的问题,请参考以下文章

将包含 int 和 int[] 的结构从 C# 编组到 C++

直接将 C++ 浮点数组成员编组到 C#,无需复制

将结构数组从 C#(.NET Core) 传递到 C++(未管理)

将 C++ 结构编组到 C# 类时出现 AccessViolationException

将复杂结构编组到 C#

C# 中的 C++ int & long 编组