2013-02-04 7 views
3

일부 코드는 구조체를 바이트 배열로 또는 바이트 배열에서로드하여 일부 공장 장비와 통신하도록 광범위하게 사용합니다.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이 나를 위해 그렇게 할 수있는 방법이있다. 그래서 나는 수백 줄의 명시 적 초기화 코드를 작성하는 것을 피할 수있다. 미리 감사드립니다!

답변

6

BYTE3_TYPE을 클래스 대신 구조체로 만들면 기본 생성자 (K_FOO origFoo = new K_FOO();을 호출)가 전체를 0으로 올바르게 초기화합니다.

기존 사양과 일치시키고이를 사용자 지정 하드웨어에 전달하려는 경우 올바른 방법 일 가능성이 높습니다.

+1

+1, [고정 크기 버퍼] (http://msdn.microsoft.com/en-gb/library/zycewsya(v=80) .aspx)를 살펴볼 수도 있습니다. 바이트 배열은 힙에 살기보다는 BYTE3_TYPE 구조체에 포함됩니다. – MattDavey

+0

안전하지 않다고 고정시켜야합니까? 지금은 안전하지 않은 코드를 사용하는 ByteArrayToStructure와 같은 몇 가지 루틴을 가지고 있지만 전반적인 프로그램을 "안전"하게 유지하고 싶습니다. – user316117

+0

@Reed - 간단한 예제로 BYTE3_TYPE을 사용했습니다. 실제 사용자 정의 유형은 바이트와 같은 기본 유형의 단순한 배열보다 복잡합니다. 내 질문의 진짜 요점은, 닷넷이 어떻게 이런 것들을 초기화하는 법을 알기 때문에 나 자신이 그것을 명시 적으로 수행하는 것보다 더 나은 방법 일까? – user316117