程序通过命名管道在C#和C++之间互发结构体,2边定义的结构体顺序和大小都一样,但是还原结构体的时候总是对不上,请大侠们帮找下问题所在,谢谢...
C++定义结构体为:typedef struct __CoData
{
int Events ;    
int Ping ;    
        int Type;                
bool  xxxxx;          
bool  yyyyy  ;         
int Num ; 
}CoData;
C#定义的结构体:
[Serializable]
    [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
    public struct stCommunicationData
    {
        public int Events;     
        public int Ping; 
        public int Type; 
        public bool xxxxx;        
        public bool yyyyy;        
        public int Num; 
     }
C#接收到结构体之后的转换:
public static Object BytesToStruct(Byte[] bytes, Type strcutType)
        {
            Int32 size = Marshal.SizeOf(strcutType);
            IntPtr buffer = Marshal.AllocHGlobal(size);
            if (size > bytes.Length)
            {
                return null;
            }
            try
            {
                Marshal.Copy(bytes, 0, buffer, size);
                return Marshal.PtrToStructure(buffer, strcutType);
            }
            finally
            {
                Marshal.FreeHGlobal(buffer);
            }
        }
网上挺多这方面例子的,但是我始终转换不对.....
起初怀疑是管道通信出了问题,将结构体去掉后,只在C++和C#间发0123456789,能够正常接收,排除了管道的问题。
加上结构体,我用C#做了一个发送一个接收,一切正常。
对C++不熟,实在是不知道上面哪个地方出了问题

解决方案 »

  1.   

    没有神人出现,咱一晚上没睡好觉,解决问题了。特别关注一下这个bool,是个大麻烦.....
      

  2.   

    c#中缺省会认为导进来的是类似于vc中BOOL的类型,所以会是4个字节(32位机上)
    而,而如果在vc++中返回的是bool(仅是1个字节),当然会出错!
    解决的两种办法:
    1. VC中返回BOOL(或是直接返回int);
    2. 在c#中加上关键字: MarshalAs(UnmanagedType.I1);
      

  3.   

    用这个:
    [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
    public struct CoData
    {
        public int Events;
        public int Ping;
        public int Type;
        [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.I1)]
        public bool xxxxx;
        [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.I1)]
        public bool yyyyy;
        public int Num;
    }