如何在C ++结构体与转换成联盟C#? [英] How to convert a C++ Struct with Union into C#?

查看:131
本文介绍了如何在C ++结构体与转换成联盟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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆