2014-10-06 3 views
0

C#에서 다음 구조체를 만들려고합니다. C 구조체를 기반으로하는 복잡한 구조체입니다. 대부분의 마샬링 옵션을 시도했지만 항상 'System'을 사용합니다. TypeLoadException '입니다.구조체가 잘못 정렬되었습니다. System.TypeLoadException

(추가 정보 : 'WindowsFormsApplication1, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null'으로 'WindowsFormsApplication1.COMPLEX_STRUCT'형식을로드 할 수 없습니다. 오프셋 8의 개체 필드가 ​​잘못 정렬되었거나 . 나는 64 기계에있어

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)] 
public string Addr; 

[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] 
public byte[] Addr; 

하지만 IPV6_ADDR : 개체가 아닌 필드에 의해 중복)

IPV6_ADDR 구조체에 관해서는, 나는 LayoutKind.Explicit 및 LayoutKind.Sequential, 모두 모두 시도 struct는 8 바이트로 정렬되어 있으므로 문제가 무엇인지 파악할 수 없습니다.

[StructLayout(LayoutKind.Sequential, Pack = 1)] 
public struct IPV4_ADDR 
{ 
    public uint Addr; 
    public uint SubnetNumBits; 
}; 

[StructLayout(LayoutKind.Explicit, Pack = 1)] 
public struct IPV6_ADDR 
{ 
    [FieldOffset(0)] 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)] 
    public string Addr; 
    [FieldOffset(16)] 
    public uint SubnetNumBits; 
}; 

[StructLayout(LayoutKind.Explicit, Pack = 1)] 
public struct COMPLEX_STRUCT 
{ 
    [FieldOffset(0)] 
    public byte A; 

    [FieldOffset(1)] 
    public byte B; 

    [FieldOffset(2)] 
    public byte C; 

    [FieldOffset(3)] 
    public byte D; 

    [FieldOffset(4)] 
    public byte E; 

    [FieldOffset(8)] 
    public IPV4_ADDR IPv4; 

    [FieldOffset(8)] 
    public IPV6_ADDR IPv6; 

    [FieldOffset(28)] 
    public ushort F; 
} 

원래 C 구조체 내가 모방하려고 :

typedef struct _IPV4_ADDR 
{ 
    uint32_t Addr; 
    uint32_t SubnetNumBits; 
} IPV4_ADDR, *PIPV4_ADDR; 

typedef struct _IPV6_ADDR 
{ 
    uint8_t Addr[16]; 
    uint32_t SubnetNumBits; 
} IPV6_ADDR, *PIPV6_ADDR; 

typedef struct _COMPLEX_STRUCT 
{ 
    uint8_t A; 
    uint8_t B; 
    uint8_t C; 
    uint8_t D; 
    uint8_t E; 
    uint8_t Rsvd[3]; 
    union { 
     IPV4_ADDR IPv4; 
     IPV6_ADDR IPv6; 
    } u; 
    uint16_t F; 
} COMPLEX_STRUCT, *PCOMPLEX_STRUCT; 
+0

@TyCobb 있습니다. 문자열은 .NET 런타임에 의해 관리되기 때문에 같은 로컬 오프셋에 문자열이없는 문자열이있는 구조체를 오버레이 할 수 없습니다. –

+0

OK Thx, 정말로 문자열에서 바이트 []/char []로 전환하는 것에 신경 쓰지는 않습니다.하지만 역시 시도해 보았습니다. 아직 좋은 것은 아닙니다. – n00b

+0

질문에 원래 구조체를 추가했습니다. 답변을 삭제하십시오. – TyCobb

답변

1

을 원래 구조체보고 IPv4와 IPv6 구조체에 대한 다른 구현보고 후, 나는 다른 구현 IPV4의 주소 byte[4]를 사용하는 것을 볼 수 .

결과가 정확하다고 보장 할 수 없지만 IPV4와 IPV6을 모두 변경하여 byte[]을 사용하도록 변경하면 오류가 사라집니다.

발견 한대로 혼합하여 일치시킬 수 없습니다. 시도 할 생각할 수있는 유일한 다른 옵션은 IntPtr을 사용하여 메모리 위치를 얻은 다음 Marshal.Copy을 사용하여 데이터를 가져 오는 것입니다.

일단 작동 시키면 결과가 정확함을 보장 할 수는 없지만.

+0

나는 그것들을 조합하고 싶습니다. IPV4와 IPV6 필드의 결합체를 가진 C 구조체를 변환하고 있습니다. 문자열에서 바이트 []/char []로 전환하는 데 정말로 신경 쓰지는 않지만 그뿐만 아니라 여전히 좋았습니다. – n00b

+0

@ n00b 아마도 byte []를 2'ulongs'. FieldOffset (0) 및 FieldOffset (8)을 가지고 있고 두 개의 long을 다시 단일 바이트 []로 병합하면 데이터로 작업해야합니다 (struct의 메서드). – TyCobb

+0

@ n00b 흉내 내고자하는 실제 구조체를 보여줄 수 있습니까? 나는 IPVx 구조체가'unint'와'string' 대신에'IntPtr'을 사용하고 있다고 생각하기 시작했습니다. – TyCobb

관련 문제