使用P / Invoke编组结构时,如何忽略字段

时间:2009-11-09 22:13:58

标签: .net pinvoke marshalling structure ignore

我想编组一个与P / Invoke一起使用的结构,但是这个结构包含一个只与我的托管代码相关的字段,因此我不希望它被编组,因为它不属于本机结构体。它甚至可能吗?我正在寻找类似于NonSerialized的属性进行序列化,但它似乎不存在...

struct MyStructure
{
    int foo;
    int bar;

    [NotMarshaled] // This attribute doesn't exist, but that's the kind of thing I'm looking for...
    int ignored;
}

任何建议都将不胜感激

3 个答案:

答案 0 :(得分:6)

无法让CLR忽略某个字段。我会改为使用两种结构,也许可以使另一种结构成为另一种结构。

struct MyNativeStructure 
{ 
    public int foo; 
    public int bar; 
} 

struct MyStructure 
{ 
    public MyNativeStruct native; 
    public int ignored; 
} 

答案 1 :(得分:1)

两种方法:

  1. 使用类而不是结构:结构总是通过指向Windows API或其他本机函数的指针传递。通过调用doThis(ref myStruct)来取代对doThis([In, Out] myClass)的呼叫应该可以解决问题。完成此操作后,您只需使用方法访问不可编组的字段即可。

  2. 正如我已经说过的那样,结构(几乎)总是通过引用传递:因此被调用者对结构维度一无所知:如何简单地将你的附加字段留作最后的字段?当调用需要你的结构指针和结构大小的本机函数时,只需要说明它的大小,给出它没有额外字段的那个。我不知道在从本机函数获取它时,是否合法地编组这样的结构。 附带问题:Marshaller处理类字段是否标记为私有? (我希望不是......)

答案 2 :(得分:0)

根据我的测试,自动属性如:

private int marshaled { get; set; }

在编组(Marshal.SizeOf)时会占用空间

但是!明确指定的属性不会:

private int skipped
{
    get { return 0; }
    set { }
}