2017-09-18 1 views
0

약 1000 요소가 포함 된 MCU에 C 구조체가 있고 내부에 고정 된 크기의 배열 및 기타 구조체가 많이 포함되어 있습니다. 이제 C#을 사용하여 데이터를 가져 오려고합니다.안전한 고정 크기 배열 구조체 C#

다음

struct _registers 
{ 
    char name[32]; 
    float calibrate[4][16]; 
    float DMTI; 
    float DMTII; 
    float DMTIII; 
    float DMTIE; 
    float DMTIIE; 
    .... 
}; 

지금 나는 GCHandle 클래스를 사용하여 C 번호로 구조체를 변환 할

C에서 내 구조체 요소의 간단한 미리보기,이

같은

뭔가

문제는 안전하지 않은 코드없이 일반적으로 사용하는 방법이 비주얼 스튜디오가 뿌려 "포인터 고정 크기 버퍼는 안전하지 않은 상황에서 사용될 수있다"

이다? 나는이

[StructLayout(LayoutKind.Explicit, Size = 56, Pack = 1)] 
public struct NewStuff 
{ 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] 
    [FieldOffset(0)] 
    public string name; 

    [MarshalAs(UnmanagedType.U4)] 
    [FieldOffset(32)] 
    public float calibrate[4][16]; 
} 

처럼 무언가를 발견했지만 MCU에 코드로 앞으로 진화와 우리가 구조체에 기능 및 매개 변수를 많이 추가되며, 구조체는 이미 1000 개 요소를 가지고 있기 때문에, 어떻게 우리는 더 잘 영리한 방법으로 그것을 할 수 있습니까? 왜냐하면 모든 옵셋 추적은 매우 어렵고 오류가 발생하기 쉽기 때문입니다!

+0

태그 스패밍이 잘못되었습니다. 네티켓 – sehe

+0

모든 필드의 크기를 올바르게 정의하는 한'FieldOffset'을 지정할 필요가 없습니다. –

+0

요소가 1000 개일 경우'_registers'를'struct'로 선언하면 안됩니다. 대신 클래스로 선언하십시오. 그렇지 않으면 각 할당은 새로운'_registers' 복사본을 만듭니다. C++의'class'와'struct'의 차이점은 C#의'class'와'struct'의 차이점과 다릅니다. –

답변

-1

하는 대신이 같은 일을 시도 (참고 : 대신 C#을 더 적합한 structclass 사용 - 아직 C의 ++ 구조체에 OK 마샬링) :

[StructLayout(LayoutKind.Sequential, Pack = 1)] 
public class NewStuff 
{ 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] 
    public StringBuilder name; 

    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4*16)] 
    public float[,] calibrate; 

    [MarshalAs(UnmanagedType.R4)] 
    public float DMTI; 

    [MarshalAs(UnmanagedType.R4)] 
    public float DMTII; 

    // Etc 
} 

당신은 제거 할 수 없습니다 마샬링이 이것을 알아야하기 때문에 SizeConst.

또한 클래스를 초기화 할 때 배열 필드를 적절한 크기의 버퍼로 설정하고 올바른 버퍼 크기로 StringBuilder을 초기화해야합니다.

이렇게하면 fixed 개의 버퍼를 사용하지 않아도됩니다. 따라서 unsafe 코드는 사용하지 않아도됩니다.

+0

[FieldOffset]이 (가) 안전하지 않습니다. 그의 코드 스 니펫은 형편 없다.'fixed' 키워드가 빠져있다. 컴파일하는 데 필요합니다. 고정 크기 버퍼는 안전하지 않으며 인덱싱은 검사되지 않습니다. –

+0

@HansPassant 예, FieldOffset에 대한 의견을 삭제했습니다. 나는 [누군가가 FieldOffset이 안전하지 않아야한다고 제안한] 오래된 토론을 잘못 기억했다. (https://stackoverflow.com/questions/4519574/should-changing-the-contents-of-a-string-like-this-cause- 예외) - 물론, 결코 그런 일은 ... –