具有 LPWSTR 和结构的显式布局的结构
Posted
技术标签:
【中文标题】具有 LPWSTR 和结构的显式布局的结构【英文标题】:Struct with explicit layout with LPWSTR and Structs 【发布时间】:2013-05-09 00:08:44 【问题描述】:对于一个 pinvoke 调用,我需要创建一个相当于以下内容的结构:
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;
【问题讨论】:
【参考方案1】:在 64 位上可能是 8 个字节。
为联合创建一个显式结构,并将其添加为 Mynet40struct 的成员,该成员保持 LayoutKind.Sequential。
【讨论】:
【参考方案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
参数来指定它。
【讨论】:
以上是关于具有 LPWSTR 和结构的显式布局的结构的主要内容,如果未能解决你的问题,请参考以下文章