Serializable : 문자로 변환하기 위해서 선언(? 알려주기정도..)해준다.
1. StructLayout(LayoutKind.Sequential) : 나 구조체야 라고 선언한다
(나 구조체야, 라는 표현보다는 마샬링 성능에 대한 부분이라 볼 수 있습니다.
[StructLayout] 키워드를 빼더라도 구조체는 사용할 수 있습니다.)
Sequential Layout은 Managed Memory에서 마샬링을 사용해 Unmanaged Memory로 옮길 때 각 필드의 순서가 Unmanaged Memory에서 유지되는 레이아웃이다. 위의 예제에서 MyStruct구조체는 [StructLayout(LayoutKind.Sequential)]을 사용하고 있는데, 이는 Managed 메모리 영역에서는 순서가 어떨지 모르지만, Unmanaged Memory로 옮겨질 때는 반드시 필드 순서대로 데이타가 옮겨진다는 것을 의미한다.
C#의 데이터가 순서대로 C++에 전달이 되어야 문제없이 사용가능하므로 [StructLayout(LayoutKind.Sequential, Size = 12)]를 사용합니다.
Size = 12부분은 구조체의 크기를 설정하는 부분 같습니다.
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(구조체) 이렇게 한거와 같은 형태가 나온다
출처: https://softworld.tistory.com/67 [시행착오]
------------------------------------------------------------------------------
'개발언어 > C#' 카테고리의 다른 글
[C#] WinAPI(Kernel32 dll) 사용하기 (0) | 2020.11.03 |
---|---|
[C#] if ~else if를 한 줄로 '삼항 연산자' (0) | 2020.11.03 |
[C#] - internal 접근 한정자 (0) | 2020.11.02 |
[C#] ref 키워드와 out 키워드의 차이 (0) | 2020.11.02 |
[C#]포인터나 핸들은 IntPtr 이용해 받기 (0) | 2020.11.02 |