Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/134.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
这些C+的C#等价物是什么+;结构 这些C++结构中的C等价是什么? < >我将一些代码从C++迁移到C语言,并迁移这些结构存在问题。我尝试了一些方法,但最终总是遇到编组问题_C#_C++_Struct_Marshalling - Fatal编程技术网

这些C+的C#等价物是什么+;结构 这些C++结构中的C等价是什么? < >我将一些代码从C++迁移到C语言,并迁移这些结构存在问题。我尝试了一些方法,但最终总是遇到编组问题

这些C+的C#等价物是什么+;结构 这些C++结构中的C等价是什么? < >我将一些代码从C++迁移到C语言,并迁移这些结构存在问题。我尝试了一些方法,但最终总是遇到编组问题,c#,c++,struct,marshalling,C#,C++,Struct,Marshalling,请参见关于使用PInvoke封送结构的说明 关键是使用StructLayout属性来确保PInvoke正确处理结构,并使用MarshalAs属性来处理不完全对齐的类型。早在.Net 2.0时代,我还拥有一个网络套接字,并将字节流转换为有意义的结构。在这个时候,唯一的解决办法就是用手工和课堂教学 不幸的是,我在网上再也找不到这个例子了。所以我脱光了我的旧课(天哪,这看起来又老又丑…)。可能是由于剥离,其中有一些小的打字错误,但它应该给你一个关于如何完成这个问题的好主意 typedef union

请参见关于使用PInvoke封送结构的说明


关键是使用
StructLayout
属性来确保PInvoke正确处理结构,并使用
MarshalAs
属性来处理不完全对齐的类型。

早在.Net 2.0时代,我还拥有一个网络套接字,并将字节流转换为有意义的结构。在这个时候,唯一的解决办法就是用手工和课堂教学

不幸的是,我在网上再也找不到这个例子了。所以我脱光了我的旧课(天哪,这看起来又老又丑…)。可能是由于剥离,其中有一些小的打字错误,但它应该给你一个关于如何完成这个问题的好主意

typedef union _Value {
    signed char    c; 
    unsigned char  b; 
    signed short   s; 
    unsigned short w; 
    signed long    l; 
    unsigned long  u; 
    float          f; 
    double        *d; 
    char          *p; 
} Value;


typedef struct _Field {
 WORD    nFieldId;
 BYTE    bValueType;
 Value Value;
} Field;


typedef struct _Packet {
 WORD    nMessageType;
 WORD    nSecurityType;
 BYTE    bExchangeId;
 BYTE    bMarketCenter;
 int     iFieldCount;
 char    cSymbol[20];
    Field FieldArr[1];

} Packet;

我假设“char”被用作8位数字,如果是这样,那么下面是您的映射:

using System;
using System.Collections.Generic;
using System.Text;

namespace VehicleSpeedTracer
{
    public class Datagram
    {
        //Offsets im ByteArray
        private const int SizeOffset = 0;
        private const int TimeOffset = SizeOffset + sizeof(uint);
        private const int SpeedOffset = TimeOffset + sizeof(double);
        private const int UnitOffset = SpeedOffset + sizeof(char);
        private const int UnitMaxSize = (int)MaxSize - UnitOffset;

        //Daten Current
        public const uint MaxSize = 128;
        public TimeSpan CurrentTime;
        public double CurrentSpeed;
        public string Unit;

        public uint Size
        {
            get { return MaxSize - (uint)UnitMaxSize + (uint)Unit.Length; }
        }

        public Datagram()
        {
        }

        public Datagram(Datagram Data)
        {
            CurrentTime = Data.CurrentTime;
            CurrentSpeed = Data.CurrentSpeed;
            Unit = Data.Unit;
        }

        public Datagram(byte[] RawData)
        {
            CurrentTime = TimeSpan.FromSeconds(GetDouble(RawData, TimeOffset));
            CurrentSpeed = GetDouble(RawData, SpeedOffset);
            Unit = GetString(RawData, UnitOffset, (int)(GetUInt(RawData, SizeOffset) - UnitOffset));
        }

        public override string ToString()
        {
            return this.CurrentTime.Hours.ToString().PadLeft(2, '0') + ":" +
                    this.CurrentTime.Minutes.ToString().PadLeft(2, '0') + ":" +
                    this.CurrentTime.Seconds.ToString().PadLeft(2, '0') + "." +
                    this.CurrentTime.Milliseconds.ToString().PadLeft(3, '0') + "  " +
                    this.Unit;
        }

        public static implicit operator byte[](Datagram Data)
        {
            byte[] RawData;
            RawData = new byte[Data.Size];
            SetUInt(RawData, SizeOffset, Data.Size);
            SetDouble(RawData, TimeOffset, Data.CurrentTime.TotalDays);
            SetDouble(RawData, SpeedOffset, Data.CurrentSpeed);
            SetString(RawData, UnitOffset, Data.Unit);

            return RawData;
        }

        #region Utility Functions
        // utility:  get a uint from the byte array
        private static uint GetUInt(byte[] aData, int Offset)
        {
            return BitConverter.ToUInt32(aData, Offset);
        }

        // utility:  set a uint into the byte array
        private static void SetUInt(byte[] aData, int Offset, uint Value)
        {
            byte[] buint = BitConverter.GetBytes(Value);
            Buffer.BlockCopy(buint, 0, aData, Offset, buint.Length);
        }

        // utility:  get a ushort from the byte array
        private static ushort GetUShort(byte[] aData, int Offset)
        {
            return BitConverter.ToUInt16(aData, Offset);
        }

        // utility:  set a ushort into the byte array
        private static void SetUShort(byte[] aData, int Offset, int Value)
        {
            byte[] bushort = BitConverter.GetBytes((short)Value);
            Buffer.BlockCopy(bushort, 0, aData, Offset, bushort.Length);
        }

        // utility:  get a double from the byte array
        private static double GetDouble(byte[] aData, int Offset)
        {
            return BitConverter.ToDouble(aData, Offset);
        }

        // utility:  set a double into the byte array
        private static void SetDouble(byte[] aData, int Offset, double Value)
        {
            byte[] bushort = BitConverter.GetBytes(Value);
            Buffer.BlockCopy(bushort, 0, aData, Offset, bushort.Length);
        }

        // utility:  get a unicode string from the byte array
        private static string GetString(byte[] aData, int Offset, int Length)
        {
            String sReturn = Encoding.ASCII.GetString(aData, Offset, Length);
            return sReturn;
        }

        // utility:  set a unicode string in the byte array
        private static void SetString(byte[] aData, int Offset, string Value)
        {
            byte[] arr = Encoding.ASCII.GetBytes(Value);
            Buffer.BlockCopy(arr, 0, aData, Offset, arr.Length);
        }
        #endregion
    }

    public delegate void DatagramEventHandler(object sender, DatagramEventArgs e);

    public class DatagramEventArgs : EventArgs
    {
        public Datagram Data;

        public DatagramEventArgs(Datagram Data)
        {
            this.Data = Data;
        }
    }
}
有了这些信息,应该可以相对容易地转换这些结构(只需确保将它们作为一个结构保存,并为其赋予属性“[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]”,这将确保封送处理程序以相同的顺序保存所有数据


另外,我建议查看System.Runtime.InteropServices中的类和属性,因为它们确实提供了很多方法来自动将数据封送到c/c++代码(而且也不需要“不安全”的c#代码).

其他一些帖子已经有了很好的信息,我想我会分享一个快速提示。我最近不得不处理这种问题。这可能是显而易见的,但如果你拥有界面两侧的代码,我发现除了一个字段外,注释所有字段并确保其工作正常,然后慢慢地逐个添加它们是非常困难的这是一种更安全的工作方式。

对不起,我没有提到;我已经在我的C#等价物上定义了StructLayout,我不想使用PInvoke。基本上,数据是以字节形式从套接字传入的,我想将它们封送到我的C#结构中。如果数据来自网络,我只会将数据包类型的固定部分声明为一个C#结构,然后通过网络流使用二进制读取器来读取剩余数据。在C#1中处理可变长度结构是非常重要的。-此方法现在确实过时了。C#3.0(可能在早期版本中可用,我只从3开始)对数据的大部分自动转换提供了极好的支持。我自己不必做任何复杂的事情来让任何c函数在c#中工作,甚至包含可变长度字符串的结构也很容易做到。是的,对于希望通过DLLImport访问的函数,这是正确的。但是如果您有一个字节[](例如,来自套接字)(据我所知)没有这样的事“代码>签名长的和<代码>未签名的长< /code >应分别映射到 ItpTrt/code >和 uTutpRT。C++中的代码>双*将映射到 ItpTrt/code >或双*,在C语言中,后者显然只允许在不安全代码中。<代码>结构布局< /代码>属性可以指定<代码>字符集.
System.Runtime.InteropServices.LayoutKind.Sequential
似乎不适合联合,联合应具有
System.Runtime.InteropServices.LayoutKind.Explicit
。有关联合,请参阅
signed char    c; -> SByte    c; 
unsigned char  b; -> Byte     b;
signed short   s; -> Int16    s;
unsigned short w; -> UInt16   w;
signed long    l; -> Int32    l;
unsigned long  u; -> UInt32   u;
float          f; -> Single   f; (though 'float' still works)
double        *d; -> Double   d; (was this meant to be a pointer???)
char          *p; -> String   s; (assuming its a string here, in the marshaling you can tell it whether it is ASCII or wide char format)