日期:2014-05-18  浏览次数:20678 次

c++与c#的转化


2 分钟前 提问者: wennuanyu110 | 浏览次数:5次
c++定义的

struct GE_MSGEvent
{
int msgtype; //消息类型,枚举值
int msglen; //消息长度
char data[1024*64]; //消息体
};
在程序中得到了 GE_MSGEvent 的对象 msg
需要获得msg.data的信息。原c++程序用了下列转换:
switch(msg.msgtype)
  {
  case EVENT_RECVDEVLIST: 
GE_DevListMsg devListMsg;
memcpy(&devListMsg,msg.data,sizeof(GE_DevListMsg));
break;}
其中GE_DevlistMsg是个结构体。
我需要,把上面代码转化到c#中 解析msg.data的信息,但是memcpy(&devListMsg,msg.data,sizeof(GE_DevListMsg));不会转,望高手指教。

------解决方案--------------------
C# code
    [StructLayout(LayoutKind.Sequential)]
    public struct GE_MSGEvent
    {
        public Int32 msgtype;
        public Int32 msglen;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1024 * 64)]
        public Byte[] data;
    }

            //...得到msg
            GCHandle gch = GCHandle.Alloc(msg.data, GCHandleType.Pinned);    //固定数组
            IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement(msg.data, 0);    //得到数组首地址
            //转化至GE_DevListMsg
            GE_DevListMsg devListMsg = (GE_DevListMsg)Marshal.PtrToStructure(ptr, typeof(GE_DevListMsg));
            gch.Free();

------解决方案--------------------
byte是基本数据类型,任何数据类型都可以转换为byte的。另外上述定义的结构体其实可以也最好这样定义:
C# code
[StructLayout(LayoutKind.Sequential)] 
public struct GE_MSGEvent
{
  public Int32 msgtype;
  public Int32 msglen;
  [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1024 * 64)]
  public string data;
}

这样定义后,得到的data就不需要手动转换到字符串了。
------解决方案--------------------
探讨
楼上正解,非常感谢。
在结贴之前我还想再问个问题:关于c++定义的数据结构向c#转化,我在网上搜了有类型对照表,为了让字节对齐,以前我都是按照对照表,把char[]重新定义成了string,但在这个例子中不行,而你在这里定义成了byte[]就可以。难道c++的一些类型可以向c#的多个类型转化,也不会出现字节不对齐的情况,我以前原以为c#封装时,类型是一一对照的。