我的这个功能是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 ++库我没有收到任何错误,我可以在同一条消息中检索我想要多少次。非常感谢任何帮助!