C#P / Invoke。 Marshal为char * __ptr32 in x64

时间:2016-10-08 04:27:10

标签: c# c++ pinvoke

原生结构

struct MailBox
{
    __time32_t time;            // receive time
    int sender;                 // mail sender (login)
    char from[64];              // mail sender (name)
    int to;                     // mail recipient
    char subject[128];          // mail sumbect
    int readed;                 // readed flag
    char* __ptr32 body;         // pointer to mail body
    int bodylen;                // mail body length
    short build_min;            // minimum build
    short build_max;            // maximum build
    int reserved;               // reserved
};

我创建的C#中的结构

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct NMailBox
{
    internal UInt32 time;               // receive time
    internal Int32 sender;              // mail sender (login)
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
    internal string from;               // mail sender (name)
    internal Int32 to;                  // mail recipient
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
    internal string subject;            // mail sumbect
    internal Int32 readed;              // readed flag
    internal Int32 body;                // readed flag
    internal Int32 bodylen;             // mail body length
    internal short build_min;           // minimum build
    internal short build_max;           // maximum build
    internal Int32 reserved;            // reserved
}

访问数据结构的类

public class MailBox : BaseModel<NMailBox>, IDisposable
{
    /// <summary>
    /// Receive time
    /// </summary>
    public DateTime Time
    {
        get { return native.time.ToDateTime(); }
        set { native.time = value.ToUInt(); }
    }

    /// <summary>
    /// Mail sender (login)
    /// </summary>
    public Int32 Sender
    {
        get { return native.sender; }
        set { native.sender = value; }
    }

    /// <summary>
    /// Mail sender (name)
    /// </summary>
    public string From
    {
        get { return native.from; }
        set { native.from = value.CorrectString(64); }
    }

    /// <summary>
    /// Mail recipient
    /// </summary>
    public Int32 To
    {
        get { return native.to; }
        set { native.to = value; }
    }

    /// <summary>
    /// Mail sumbect
    /// </summary>
    public string Subject
    {
        get { return native.subject; }
        set { native.subject = value.CorrectString(128); }
    }

    /// <summary>
    /// Readed flag
    /// </summary>
    public Int32 Readed
    {
        get { return native.readed; }
        set { native.readed = value; }
    }

    public string Body
    {
        get
        {
            return Marshal.PtrToStringAnsi(native.body, native.bodylen);
        }
        set
        {
            if (native.body != IntPtr.Zero)
            {
                BodyFree();
                if (native.body != IntPtr.Zero)
                    throw new Exception(nameof(native.body));
            }

            native.body = Marshal.StringToHGlobalAnsi(value);
            native.bodylen = value.Length;
        }
    }

    /// <summary>
    /// Minimum build
    /// </summary>
    public short BuildMin
    {
        get { return native.build_min; }
        set { native.build_min = value; }
    }

    /// <summary>
    /// Maximum build
    /// </summary>
    public short BuildMax
    {
        get { return native.build_max; }
        set { native.build_max = value; }
    }

    /// <summary>
    /// Reserved
    /// </summary>
    public Int32 Reserved
    {
        get { return native.reserved; }
    }

    private void BodyFree()
    {
        if (native.body != IntPtr.Zero)
        {
            var pointer = native.body;
            Marshal.FreeHGlobal(pointer);
            native.bodylen = 0;
        }
    }

    public void Dispose()
    {
        BodyFree();
    }
}

带有签名的本机函数中使用的结构

virtual int __stdcall MailSend(const MailBox* mail,const int *logins)=0;

代表我为它创建的

[UnmanagedFunctionPointer(CallingConvention.StdCall)]
protected delegate ResultCode MailSendDelegate(IntPtr Obj, ref NMailBox mail, [In] int[] logins);

问题是当我调用一个天真的函数并将准备好的结构发送给它时,我得到了 AccessViolationException

告诉我如何修复错误?

0 个答案:

没有答案