2011-10-02 4 views
0

struct (C# 파일의 extern으로 선언 된) C 구조체에 구조체를 전달해야하는 상황이 있습니다.내부 바이트 배열을 사용하여 구조체를 interoped 메서드로 전달

그러나이 구조체는 상당히 복잡합니다. 나는 이미 AllocHGlobal과 함께 접근법을 성공적으로 사용했지만 구조체에 대한 참조 만 전달함으로써이 방식으로 작동하는지 이해하고 싶습니다.

[StructLayout(LayoutKind.Sequential)] 
struct lgLcdBitmapHeader 
{ 
    public Formats Format; 
} 

[StructLayout(LayoutKind.Explicit)] 
struct lgLcdBitmap 
{ 
    [FieldOffset(0)] 
    public lgLcdBitmapHeader hdr; 
    [FieldOffset(0)] 
    public lgLcdBitmap160x43x1 bmp_mono; 
    [FieldOffset(0)] 
    public lgLcdBitmapQVGAx32 bmp_qvga32; 
} 

[StructLayout(LayoutKind.Sequential)] 
struct lgLcdBitmap160x43x1 : IDisposable 
{ 
    /// <summary> 
    /// Format = LGLCD_BMP_FORMAT_160x43x1 
    /// </summary> 
    public lgLcdBitmapHeader hdr; 
    /// <summary> 
    /// byte array of size LGLCD_BMP_WIDTH * LGLCD_BMP_HEIGHT, use AllocHGlobal to make code safe 
    /// </summary> 
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)BWBitmapSizes.Size)] 
    internal byte[] pixels; 
} 

[StructLayout(LayoutKind.Sequential)] 
struct lgLcdBitmapQVGAx32 : IDisposable 
{ 
    /// <summary> 
    /// Format = LGLCD_BMP_FORMAT_160x43x1 
    /// </summary> 
    public lgLcdBitmapHeader hdr; 
    /// <summary> 
    /// byte array of size LGLCD_QVGA_BMP_WIDTH * LGLCD_QVGA_BMP_HEIGHT * LGLCD_QVGA_BMP_BPP, use AllocHGlobal to make code safe 
    /// </summary> 
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)QVGABitmapSizes.Size)] 
    internal byte[] pixels; 
} 

가장 큰 문제는 모든 것을 노동 조합 (lgLcdBitmap 구조체)으로 포장해야한다는 것입니다. 오프셋 0에 정확하게 정렬되지 않았거나 다른 개체와 겹치는 개체가 있기 때문에 실제로 C#이 만족 스럽습니다.

제 생각에이 문제는 제 바이트 배열에 실제 크기 (SizeConst로 선언 된 것)가 없다고 생각됩니다. 고정을 사용하고 싶지 않기 때문에 (안전하지 않은 코드를 사용하도록 강요합니다) 어떻게 해결할 수 있는지 알고 싶습니다.

내가 생각할 수있는 유일한 생각은 Size (StructLayout 내부)를 선언하여 C#이 구조체인지 이해할 수 있지만 작동 여부를 확신 할 수 없습니다. 모든 작품 만드는 방법에 대한

public extern static uint lgLcdUpdateBitmap([In] int device, [In] ref lgLcdBitmap bitmap, [In] Priorities priority); 

어떤 제안 :

내가 전화를해야하는 방법이 하나?

답변

0

fixed을 사용하고 싶지 않으므로 바이트 배열은 AllocHGlobal으로 할당되고 Marshal.Copy을 사용하여 데이터로 채워진 IntPtr으로 가장 잘 선언됩니다. MarshalAs을 사용하여 P/invoke 마샬 러에게 필요한 것을 수행 할 수있는 방법이 없습니다.

+0

불행히도, 당신이 옳다고 생각합니다. 나는 다른 길을 찾을 수 없다 : \ –

1

관리 코드에서 유니온이 필요하지 않은 경우 유니온으로 설정하지 마십시오. 두 개의 구조체와 p/invoke 함수의 두 가지 오버로드를 선언하십시오.

관련 문제