2013-05-09 152 views
0

對於PInvoke的來電顯式佈局我需要一個結構相當於說以下內容:結構與LPWSTR和結構

typedef struct _Somenativestruct { 
PCWSTR filename; 
DWORD count; 
DWORD anothercount; 
AnEnumWithByteSize info; 
union { 
    Structwithoneintfield Progress; 
    Anotherstructwithoneintfield Result; 
}; 
} Somenativestruct , *PSomenativestruct ; 

因爲它有一個工會的結構我必須使它layout.explicit但問題是我將爲PCWSTR的文件名所做的偏移量是多少。 由於它的32位指針可以提供4的偏移量?以下是正確的嗎?

[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)] 
    public struct Mynet40struct 
    { 
     [FieldOffset(0)] 
     private [MarshalAs(UnmanagedType.LPWStr)] string filename; 
     [FieldOffset(4)] 
     private int count; 
     [FieldOffset(8)] 
     private int anothercount; 
     [FieldOffset(12)] 
     AnEnumWithByteSize info; 
     [FieldOffset(13)] 
     StructWithOneIntField progress; 
     [FieldOffset(13)] 
     AnotherStructWithOneIntField result; 
    } 

回答

2

它可能是64位的8個字節。

僅爲聯合創建一個顯式結構,並將其添加爲保持LayoutKind.Sequential的Mynet40struct的成員。

2

這裏有幾個值得考慮的問題。

首先,你已經假設了一個打包佈局。也許本地結構真的很包裝,但這是不尋常的。結構對齊是正常的。除非本地聲明包含#pragma pack指令,否則您的結構將被對齊。其次,對於32位和64位目標,指針的大小是不同的,所以你對顯式的使用只能適用於一個目標。處理這個問題的方法是僅爲聯合使用明確的佈局。這是處理工會的最好方式。

[StructLayout(LayoutKind.Explicit)] 
public struct Mynet40union 
{ 
    [FieldOffset(0)] 
    StructWithOneIntField progress; 
    [FieldOffset(0)] 
    AnotherStructWithOneIntField result; 
} 

然後在你的結構中使用這個聯合。

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 
public struct Mynet40struct 
{ 
    string filename; 
    int count; 
    int anothercount; 
    AnEnumWithByteSize info; 
    Mynet40union progressOrResult; 
} 

如果你的結構真的是擠滿然後使用StructLayout屬性的Pack參數指定。