编组包含wchar_t *的C结构

时间:2016-11-29 18:27:52

标签: c# c struct marshalling wchar-t

我的这个功能是C dll:

extern "C" SIBIO_MULTILANGUAGE_API_C DWORD getMsgToUse(const uint16_t i_msgId, MsgToUse* i_output);

其中struct MsgToUse的定义如下:

typedef struct
{
    wchar_t * msgName;
    wchar_t * msgTitle;
    wchar_t * msg;
    wchar_t * view;
    wchar_t * defaultRes;
    wchar_t * alternativeMsg;
    wchar_t * msgIcon;
    wchar_t * msgIconAlt;
    DWORD msgTimeout;
}MsgToUse;

在C#中,我编写了以下包装器:

[DllImport("sibio_multilanguage_c.dll", EntryPoint = "getMsgToUse", CallingConvention = CallingConvention.Cdecl)]
private static extern UInt32 _getMsgToUse([In] UInt16 i_msgId, ref MsgToUse i_output);

static public MsgToUse getMsgToUse(UInt16 i_msgId)
{
    MsgToUse message = new MsgToUse();
    UInt32 err = _getMsgToUse(i_msgId, ref message);
    return message;
}

如果我在C#程序中调用此函数两次(使用相同的msgId):

using System;
using System.Collections.Generic;
using SibioMultilanguageWrap;
using System.Windows.Forms;
using SiliconBiosystems.Controls.Log;
using SiliconBiosystems.Controls.MsgBox;
using System.Text;

namespace Test_sibio_multilanguage
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                MsgToUse message = SibioMultilanguage.getMsgToUse(16);
                MsgToUse message1 = SibioMultilanguage.getMsgToUse(16);
            }
            catch (Exception e)
            {
                Console.Out.WriteLine(e.ToString());
            }
        }
    }
}

第一次一切正常,我能够正确阅读信息。第二次C#程序崩溃时出现以下错误:

  

堆腐败例外0xC0000374

我做错了什么?

更新

我忘了提到在C#中我将struct MsgToUse定义如下:

[StructLayout(LayoutKind.Sequential)]
public struct MsgToUse
{
    [MarshalAs(UnmanagedType.LPWStr)]
    public string msgName;
    [MarshalAs(UnmanagedType.LPWStr)]
    public string msgTitle;
    [MarshalAs(UnmanagedType.LPWStr)]
    public string msg;
    [MarshalAs(UnmanagedType.LPWStr)]
    public string view;
    [MarshalAs(UnmanagedType.LPWStr)]
    public string defaultRes;
    [MarshalAs(UnmanagedType.LPWStr)]
    public string alternativeMsg;
    [MarshalAs(UnmanagedType.LPWStr)]
    public string msgIcon;
    [MarshalAs(UnmanagedType.LPWStr)]
    public string msgIconAlt;
    public Uint32 msgTimeout;
}

C库反过来是C ++ DLL的包装器。 C ++代码有一个包含成员数据std::unordered_map<uint16_t,MsgToUse> msgTable的类和一个成员函数:

DWORD getMsgToUse(uin16_t msgId, MsgToUse & msg)
{
    std::unordered_map<uint16_t,MsgToUse>::const_iterator got = msgTable.find(msgId);
    if(msgTable.end() != got)
    {
        msg = got->second;
    }
    else
    {
       msg = MsgToUse();
    }

    return 0;
}

我很确定这是一个与编组有关的问题,因为如果我在C / C ++程序中使用C / C ++库我没有收到任何错误,我可以在同一条消息中检索我想要多少次。非常感谢任何帮助!

0 个答案:

没有答案