问题描述
我在调用DLL中的函数之后,在检索struct成员值时遇到困难。我试图将C ++代码转换为C#,但我不知道如果它是否正确。请帮助我理解我在这里的错误(如果有)以及如何更正。
我的问题是我无法正确检索INNER STRUCTS )我从DLL中调用ReceiveMessage函数。像例如m_objMsg.MsgData.StartReq.MsgID总是0.
但是当我尝试使用C ++ .exe程序时,MsgID有一个正确的值。 (非0)
C ++代码:
extern int ReceiveMessage SESSION,int,Msg *);
typedef struct
{
char SubsId [15];
int Level;
char选项[12];
} ConxReq;
typedef struct
{
char MsgId [25];
} StartReq;
typedef struct
{
long Length;
short类型;
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#
[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选项;
}
[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 SWITCH条件
struct in the UNION for c ++ and c#...
我有一个错误,说明...不正确对齐或... overlapped ...
c ++
ConxNack oConxNack;
typedef struct
{
int原因;
} ConxNack;
[StructLayout(LayoutKind.Sequential)]
public struct ConxNack
{
public int nReason;
}
[FieldOffset(0)]
public ConxNack oConxNack;非常感谢您的时间和帮助... b 解决方案 Akash是对的,看看这里: http://social.msdn.microsoft.com/Forums/en/csharplanguage/thread/60150e7b-665a-49a2-8e2e-2097986142f3
另一个选项是创建两个结构体,并在知道它是哪个类型后使用适当的转换。
hth
马里奥
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.
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++ Code:
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;
…
}
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
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...
解决方案 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.
hth
Mario
这篇关于如何将C ++ Struct与Union转换为C#?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!