如何在C ++结构体与转换成联盟C#? [英] How to convert a C++ Struct with Union into C#?
问题描述
大家好我有关于调用DLL中的函数后,检索结构成员的值的困难。我试图把C ++代码转换成C#,但我不知道这是否是正确与否。请帮助我了解我的错误在这里(如果有的话),以及如何纠正。
Guys I am having difficulties on retrieving struct member values after calling a function in the DLL. I tried to convert the C++ codes into C# but I’m not sure if it is correct or not. Please help me understand my mistakes here (if there is) and how to correct.
在这里我的问题是,我不能正确检索内部结构的值(联盟)后,我打电话从DLL ReceiveMessage功能。例如像m_objMsg.MsgData.StartReq.MsgID始终为0
但当我尝试使用C ++的.exe程序中,具有的MsgID一个正确的值。 (不为0)
My problem here is I can’t correctly retrieved the values of the INNER STRUCTS (Union) after I called the ReceiveMessage function from the DLL. Like for example m_objMsg.MsgData.StartReq.MsgID is always 0. But when I try to use the C++ .exe program, the MsgID has a correct value. (not 0)
C ++代码:
extern int ReceiveMessage(SESSION, int, Msg*);
typedef struct
{
char SubsId[15];
int Level;
char Options[12];
} ConxReq;
typedef struct
{
char MsgId[25];
} StartReq;
typedef struct
{
long Length;
short Type;
union
{
ConxReq oConxReq;
StartReq oStartReq;
} Data;
} Msg;
/////////////////////////////////////////////////////
Msg oMsg;
int rc=ReceiveMessage(Session, 0, &oMsg);
switch(rc)
{
case 0:
switch(oMsg.Type)
{
case 0: // ConxReq
…
break;
case 1: // StartReq
…
break;
…
}
这是我尝试将它转换成C#:
And here is my attempt to convert this into c#:
[DllImport("MyDLL.dll",
CallingConvention = CallingConvention.Cdecl,
CharSet = CharSet.Ansi)]
protected static extern Int32 ReceiveMessage(IntPtr session,
Int32 nTimeOut,
[MarshalAs(UnmanagedType.Struct)] ref Msg ptrMsg);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct ConxReq
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 15)]
public string SubsId;
public Int32 Level;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 12)]
public string Options;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct StartReq
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 25)]
public string MsgId;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
protected struct Msg
{
public int Length;
public Int16 Type;
public Data MsgData;
}
StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi)]
public struct Data
{
[FieldOffset(0)]
public ConxReq oConxReq;
[FieldOffset(0)]
public StartReq oStartReq;
}
Msg m_objMsg = new Msg();
m_objMsg.MsgData = new Data();
m_objMsg.MsgData.oConxReq = new ConxReq();
m_objMsg.MsgData.oStartReq = new StartReq();
int rc = ReceiveMessage(m_Session, nTimeOut, ref m_objMsg);
then the SWITCH Condition
如果我添加此该联盟C ++和C#...
内部结构我有一个错误,说明了......正确对齐或... ...重叠
And If I add this struct inside the UNION for c++ and c#... I've got an error stating the "... incorrectly align" or "...overlapped..."
C ++
ConxNack oConxNack;
typedef struct
{
int Reason;
} ConxNack;
[StructLayout(LayoutKind.Sequential)]
public struct ConxNack
{
public int nReason;
}
[FieldOffset(0)]
public ConxNack oConxNack;
感谢你这么多提前为你的时间和帮助...
Thank you so much in advance for your time and help...
推荐答案
阿卡什是正确的,看看这里:的 http://social.msdn.microsoft.com/Forums/en/csharplanguage/thread/60150e7b-665a-49a2-8e2e-2097986142f3
Akash is right, have a look here: http://social.msdn.microsoft.com/Forums/en/csharplanguage/thread/60150e7b-665a-49a2-8e2e-2097986142f3
另一种选择是创建两个结构,一旦你知道哪些类型是使用合适的演员。
Another option is create two structs and use an appropriate cast once you know which type it is.
心连心
马里奥
这篇关于如何在C ++结构体与转换成联盟C#?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!