2012-04-14 10 views
2

にC構造体のマーシャリング:無効構造サイズ、私は次のC-の構造に問題が発生しています.NET

typedef struct tagTEXTUREPROP 
{ 
    DWORD dwSize; 
    DOUBLE eGloss; 
    DOUBLE eContrast; 
    BOOL bRepeat; 
    DOUBLE eDropX; 
    DOUBLE eDropY; 
    DOUBLE ePlacingPointX; 
    DOUBLE ePlacingPointY; 
    DOUBLE eWidth; 
    DOUBLE eHeight; 
    LONG nTransformation; 
} 
TEXTUREPROP; 

TYPE  C/C++   Description 
------------------------------------------------------------------- 
DWORD unsigned long Unsigned 32-bit integer. 
DOUBLE double   Double precision floating point (64-bit). 
BOOL  int    Signed 32-bit integer. 
LONG  long    Signed 32-bit integer. 
私は上記のコードから理解何

と構造体のサイズは76バイトでなければならないということです。これは、私が現在使用している元のDLL関数が、構造体メンバdwSizeの値として期待しているものです。他の値が無効な構造体サイズのエラーメッセージを生成します。

私は.NETラッパーを生成しているので、マーシャリングを行う必要があります。ここでは構造の私の翻訳です:

<StructLayoutAttribute(LayoutKind.Explicit)> 
    Friend Structure TEXTUREPROP 
    <FieldOffset(0)> <MarshalAsAttribute(UnmanagedType.U4)> Public dwSize As UInteger 
    <FieldOffset(4)> <MarshalAsAttribute(UnmanagedType.R8)> Public eGloss As Double 
    <FieldOffset(12)> <MarshalAsAttribute(UnmanagedType.R8)> Public eContrast As Double 
    <FieldOffset(20)> <MarshalAsAttribute(UnmanagedType.I4)> Public bRepeat As Integer 
    <FieldOffset(24)> <MarshalAsAttribute(UnmanagedType.R8)> Public eDropX As Double 
    <FieldOffset(32)> <MarshalAsAttribute(UnmanagedType.R8)> Public eDropY As Double 
    <FieldOffset(40)> <MarshalAsAttribute(UnmanagedType.R8)> Public ePlacingPointX As Double 
    <FieldOffset(48)> <MarshalAsAttribute(UnmanagedType.R8)> Public ePlacingPointY As Double 
    <FieldOffset(56)> <MarshalAsAttribute(UnmanagedType.R8)> Public eWidth As Double 
    <FieldOffset(64)> <MarshalAsAttribute(UnmanagedType.R8)> Public eHeight As Double 
    <FieldOffset(72)> <MarshalAsAttribute(UnmanagedType.I4)> Public nTransformation As Integer 
    End Structure 

構造のサイズを計算するために、私は次のコードを使用し

Dim pFTP As New TEXTUREPROP With {.dwSize = Marshal.SizeOf(GetType(TEXTUREPROP))} 

をしかしdwSizeの結果の値は、現在80なく76で、どの上記の構造体サイズエラーが無効になります。

When I change the structure to: 

<StructLayoutAttribute(LayoutKind.Explicit, Size:=76, CharSet:=CharSet.Ansi)> _ 
    Friend Structure FACE_TEXTUREPROP 
    [...] 
    End Structure 

Marshal.SizeOfは明らかに76の大きさを計算し、それがDLL関数で動作しますが、それはいくつかの悪い気持ちで私を残します。何か悪いですか?私が今考えていないエラーはありますか?

答えて

0

指定した明示的なレイアウトは、[StructLayout]のデフォルトのパック値と互換性がありません。デフォルトは8で、Doubleを配置する前に余分な4バイトのパディングを挿入する必要があります。 Pinvoke Marshallerは、パッキングに基づいて構造サイズを計算することでこれを少し浮かせます。明示的にパッキングを指定して

修正これを:

<StructLayout(LayoutKind.Explicit, Size:=76)> _ 
'' etc 

正しく梱包を指定の大きな利点は、もはや今ではあなたです:

<StructLayout(LayoutKind.Explicit, Pack:=4)> _ 
Friend Structure TEXTUREPROP 
    '' etc 
End Structure 

が明示的にもそれを修正するSizeプロパティを設定します明示的にオフセットを指定する必要があります。単純なLayoutKind.Sequentialだけが正しく動作します。

+0

あなたの権利があります。私が言及しておかなければならないのは、オフセットをドロップするとLayoutKind.Sequentialをもう一度作成する必要があることだけです。 – Michael

+0

さて、良いこと! –

関連する問題