C# 마샬링 구조체로 가지고 놀아보자..

|
Serializable : 문자로 변환하기 위해서 선언(? 알려주기정도..)해준다.
StructLayout(LayoutKind.Sequential) : 나 구조체야 라고 선언한다

Pack=1
: Pack 단위로 만든다(Size만큼 정확히 만들어 준다)
CharSet=CharSet.Ansi : OS의 구조체 Padding값도 들어가 계산된다.

    어떻게? 선언한 순서로 순차적으로 만들어 줘 라고
MarshalAs(UnmanagedType.ByValArray, SizeConst = 배열수)
    배열을 만들꼬다.. , (SizeConst = )개수 만큼!
이 외에도 UnmanagedType.ByValTStr(문자배열 Type은 string으로 줘도 된다)

    [Serializable]
    [StructLayout(LayoutKind.Sequential, Pack=1)]
    public struct _HMIData
    {
        public _hmi_macsta hmi_macsta
    }
    [Serializable]
    [StructLayout(LayoutKind.Sequential, Pack=1)]
    public struct _hmi_macsta
    {
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1100]
        public short[] oth_sta;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 298)]
        public short[] bcdv_sta1;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 298)]
        public short[] bcdv_sta2;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst= 15)]
        public string start_time;
    }


열쉬미 만들었으면 생성해서 Read And Write ~~!!


    public partial class ShmDataView : Form
    {
        public _HMIData HMIData;
        public int ShmStructSize;
        public byte[] HMIBuffer;

	public ShmDataView()
        {
            InitializeComponent();
            InitHMIData();
        }

        private void InitHMIData()
        {
            HMIData = new _HMIData();
            ShmStructSize = Marshal.SizeOf(HMIData);
            HMIBuffer = new byte[ShmStructSize];
	    HMIData = (_HMIData)RawDeSerialize(HMIBuffer, HMIData.GetType());
        }


        public byte[] RawSerialize(object ShmStruct)
        {
            IntPtr buffer = Marshal.AllocHGlobal(ShmStructSize);
            Marshal.StructureToPtr(HMIData, buffer, false);
            byte[] RawData = new byte[ShmStructSize];
            Marshal.Copy(buffer, RawData, 0, ShmStructSize);
            Marshal.FreeHGlobal(buffer);
            return RawData;
        }

        public object RawDeSerialize(byte[] RawData, Type ShmData)
        {
            int RawSize = Marshal.SizeOf(ShmData);

            //Size Over
            if (RawSize > RawData.Length)
            {
                return null;
            }

            IntPtr buffer = Marshal.AllocHGlobal(RawSize);
            Marshal.Copy(RawData, 0, buffer, RawSize);
            object retobj = Marshal.PtrToStructure(buffer, ShmData);
            Marshal.FreeHGlobal(buffer);
            return retobj;
        }
    }


public byte[] RawSerialize(object ShmStruct)
요녀석은 구조체로 되어있는 내용은 byte배열로 만들어준다

public object RawDeSerialize(byte[] RawData, Type ShmData)
요녀석은 byte배열로 되어있는 녀석을 구조체(object)로 반환해 준다.

그냥 sizeof하믄 안나온다
Marshal.SizeOf(객체)
이정도로 해줘야 C언어의 sizeof(구조체) 이렇게 한거와 같은 형태가 나온다
Trackback 0 And Comment 1
  1. 요원009 2016.11.01 13:32 신고 address edit & del reply

    "StructLayout(LayoutKind.Sequential) : 나 구조체야 라고 선언한다"

    나 구조체야, 라는 표현보다는 마샬링 성능에 대한 부분이라 볼 수 있습니다. [StructLayout] 키워드를 빼더라도 구조체는 사용할 수 있습니다.

    민감한 정보를 담거나, 정확도, 빠른 속도에 대응하기 위해선 위의 옵션을 바꿔보는 것도 좋은 방법이 되겠죠.