【问题标题】:How can I ignore a field when marshalling a structure with P/Invoke使用 P/Invoke 编组结构时如何忽略字段
【发布时间】:2021-08-11 07:43:15
【问题描述】:

我想编组一个用于 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;
}

任何建议将不胜感激

【问题讨论】:

    标签: .net structure pinvoke marshalling


    【解决方案1】:

    没有办法让 CLR 忽略一个字段。我会改为使用两个结构,并且可能使一个成为另一个的成员。

    struct MyNativeStructure 
    { 
        public int foo; 
        public int bar; 
    } 
    
    struct MyStructure 
    { 
        public MyNativeStruct native; 
        public int ignored; 
    } 
    

    【讨论】:

    • “没有办法让 CLR 忽略一个字段”:是的,你可能是对的……我会等几天,以防有人有其他想法,但这可能是最好的答案我会得到。谢谢!
    【解决方案2】:

    两种方法:

    1. 使用类而不是结构:结构总是通过指向 Windows API 或其他本机函数的指针传递。用对doThis([In, Out] myClass) 的调用替换对doThis(ref myStruct) 的调用应该可以解决问题。完成此操作后,您可以简单地使用方法访问您的不可封送字段。

    2. 1234563当调用需要结构指针和结构大小的本机函数时,只需谎报其大小,给出没有额外字段的情况。我不知道在从本机函数中获取这种结构时,将其编组回来是否合法。 附带问题:Marshaller 是否处理标记为私有的类字段? (我希望不会……)

    【讨论】:

    • 私有字段也被封送
    【解决方案3】:

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

    private int marshaled { get; set; }
    

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

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

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

    【讨论】:

    • 那是因为您的显式属性没有支持字段。字段占用空间,方法和属性不占用。自动属性有一个隐含的支持字段。
    • @ThomasLevesque 你完全正确!太傻了,我忘了自动属性背景
    猜你喜欢
    • 2012-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-18
    • 1970-01-01
    相关资源
    最近更新 更多