일부 코드는 구조체를 바이트 배열로 또는 바이트 배열에서로드하여 일부 공장 장비와 통신하도록 광범위하게 사용합니다.C#에서 구조체 초기화?
다음은 이러한 구조체로 구성된 매우 간단한 예제입니다.
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct K_FOO
{
public byte a_byte; // 1 byte
public BYTE3_TYPE b3; // 3 bytes
public int num; // happens to be 4 bytes
}
BYTE3_TYPE 난 그냥
K_FOO origFoo = new K_FOO();
INT와 바이트가 0의 초기화됩니다 않는 경우, 기본 유형이기 때문에, 나는 가정
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public class BYTE3_TYPE
{
[System.Runtime.InteropServices.MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public byte[] L = new byte[3];
}
... 다음과 같습니다 그러나 바이트 배열 b3은 * un * 초기화 됨 - 모두 null입니다. 나는 명시 적으로, 예를 들어,
BYTE3_TYPE b3 = new BYTE3_TYPE();
origFoo.b3 = b3;
를로드해야 ... 그리고 구조체는 매개 변수가없는 생성자를하지 않지만 실제 구조체가 거대하기 때문에 나는 어떤 다른 생각하지 못했습니다.
하지만 흥미로운 것을 발견했습니다. 이 구조체를 바이트 배열로 복사하거나 복사하는 루틴이 있습니다. 예를 들어. . .
public static T ByteArrayToStructure<T>(byte[] buffer) where T : struct
{
int length = buffer.Length;
IntPtr ptr = Marshal.AllocHGlobal(length); // allocate (length) bytes
Marshal.Copy(buffer, 0, ptr, length); // copies into UNmanaged space
T result = (T)Marshal.PtrToStructure(ptr, typeof(T));
Marshal.FreeHGlobal(ptr);
return result;
}
... 그리고 내가 전화하면 ...
K_FOO retFoo = ByteArrayToStructure<K_FOO>(buffer.bytes);
가 ... 결과 구조체가 완전히 초기화 반환, 바이트 배열의 바이트가 모든 공간을 할당 한 한 그들은 그렇게 분명히
PtrToStructure() 호출에로드 될 수 있습니다. 이것은 .NET이 그러한 구조체를 초기화하는 방법을 "안다"는 것을 의미합니다. 그래서 .Net이 나를 위해 그렇게 할 수있는 방법이있다. 그래서 나는 수백 줄의 명시 적 초기화 코드를 작성하는 것을 피할 수있다. 미리 감사드립니다!
+1, [고정 크기 버퍼] (http://msdn.microsoft.com/en-gb/library/zycewsya(v=80) .aspx)를 살펴볼 수도 있습니다. 바이트 배열은 힙에 살기보다는 BYTE3_TYPE 구조체에 포함됩니다. – MattDavey
안전하지 않다고 고정시켜야합니까? 지금은 안전하지 않은 코드를 사용하는 ByteArrayToStructure와 같은 몇 가지 루틴을 가지고 있지만 전반적인 프로그램을 "안전"하게 유지하고 싶습니다. – user316117
@Reed - 간단한 예제로 BYTE3_TYPE을 사용했습니다. 실제 사용자 정의 유형은 바이트와 같은 기본 유형의 단순한 배열보다 복잡합니다. 내 질문의 진짜 요점은, 닷넷이 어떻게 이런 것들을 초기화하는 법을 알기 때문에 나 자신이 그것을 명시 적으로 수행하는 것보다 더 나은 방법 일까? – user316117