简体   繁体   English

这些C ++结构的C#等价物是什么

[英]What are the C# equivalent of these C++ structs

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;

What are the C# equivalent of these C++ structs? 这些C ++结构的C#等价物是什么?

I am migrating some code from C++ to C# and having problems to migrate these structures. 我正在将一些代码从C ++迁移到C#,并且在迁移这些结构时遇到问题。 I had tried a few things but I always ended up having marshalling problems. 我曾尝试过一些东西,但我总是遇到编组问题。

I'm assuming the 'char' is being used as an 8 bit number, if so, then here are you're mappings: 我假设'char'被用作8位数,如果是这样,那么这里是你的映射:

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)

With this info it should be relatively easy to translate those strucutres (just make sure you keep them as a struct and give it the attribute "[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]", which will make sure that the marshaller keeps all the data in the same order. 有了这些信息,翻译这些结构应该相对容易(只需确保将它们保存为结构并赋予它属性“[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]”,这将确保编组器以相同的顺序保存所有数据。

Also, I recommend looking through both the classes and attributes in System.Runtime.InteropServices as they do provide quite a few methods for automating marshaling of data to c/c++ code (and it doesn't require "unsafe" c# code either). 另外,我建议查看System.Runtime.InteropServices中的类和属性,因为它们提供了很多方法来自动将数据封送到c / c ++代码(并且它也不需要“不安全”的c#代码)。

See this MSDN article on marshaling structs with PInvoke. 有关PInvoke的编组结构,请参阅此MSDN文章

The key is using the StructLayout attribute to ensure that the struct is treated properly by PInvoke, and the MarshalAs attribute for types that don't line up exactly. 关键是使用StructLayout属性来确保PInvoke正确处理结构,并确保不完全排列的类型的MarshalAs属性。

Some of the other posts already have great information, I thought I would share a quick tip. 其他一些帖子已经有了很多信息,我想我会分享一个快速提示。 I had to go through this kind of issue recently. 我最近不得不经历这样的问题。 It may be obvious but if you own the code to both sides of the interface I found that commenting out all but the one fields and making sure that works and then adding them back slowly one by one was a much safer way to get this working. 这可能是显而易见的,但是如果你拥有接口双方的代码,我发现除了一个字段之外的所有内容并且确保工作然后逐个慢慢地添加它们是一种更加安全的方式来实现这一点。

Back in .Net 2.0 days i also had a network socket and to convert the byte stream into a meaningful structure. 回到.Net 2.0天,我还有一个网络套接字,并将字节流转换为有意义的结构。 At this time there was the only solution to do it by hand with BitConverter and Buffer class. 此时,唯一的解决方案是使用BitConverterBuffer类手动完成。

Unfortunately i couldn't find the example on the web again. 不幸的是我再也找不到网上的例子。 So i stripped down my old class (gosh, this looks so old and ugly...). 所以我剥夺了我的旧班级(天哪,这看起来很古老,丑陋......)。 Maybe due to strip down, there are some small typo errors within it, but it should give you a good idea on how to accomplish the problem. 也许由于条带下降,其中有一些小错字错误,但它应该让你知道如何解决问题。

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;
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM