本文介绍了如何将C ++ Struct与Union转换为C#?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在调用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#?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-29 02:06