What are the C# equivalent of these C++ structs

前端 未结 4 2025
感情败类
感情败类 2020-12-30 16:52
typedef union _Value {
    signed char    c; 
    unsigned char  b; 
    signed short   s; 
    unsigned short w; 
    signed long    l; 
    unsigned long  u; 
             


        
相关标签:
4条回答
  • 2020-12-30 17:03

    See this MSDN article on marshaling structs with PInvoke.

    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.

    0 讨论(0)
  • 2020-12-30 17:07

    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.

    0 讨论(0)
  • 2020-12-30 17:13

    I'm assuming the 'char' is being used as an 8 bit number, if so, then here are you're mappings:

    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.

    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).

    0 讨论(0)
  • 2020-12-30 17:13

    Back in .Net 2.0 days i also had a network socket and to convert the byte stream into a meaningful structure. At this time there was the only solution to do it by hand with BitConverter and Buffer class.

    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;
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题