How can I ignore a field when marshalling a structure with P/Invoke
Asked Answered
B

3

15

I want to marshal a structure for use with P/Invoke, but this struct contains a field that is only relevant to my managed code, so I don't want it to be marshaled since it doesn't belong in the native structure. Is it even possible ? I was looking for an attribute similar to NonSerialized for serialization, but it doesn't seem to exist...

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;
}

Any suggestion would be appreciated

Billingsley answered 9/11, 2009 at 22:13 Comment(0)
A
7

There's no way to make the CLR ignore a field. I would instead use two structures, and perhaps make one a member of the other.

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

struct MyStructure 
{ 
    public MyNativeStruct native; 
    public int ignored; 
} 
Anthology answered 11/11, 2009 at 9:2 Comment(1)
"There's no way to make the CLR ignore a field" : yes, you're probably right... I'll wait a few days in case someone has another idea, but that's probably the best answer I'll get. Thanks !Billingsley
B
1

Two methods:

  1. Use a class instead of a struct: structures are always passed by pointer to the Windows API or other native functions. Replacing a call to doThis(ref myStruct) with a call to doThis([In, Out] myClass) should do the trick. Once you've done this, you can simply access your not-to-be-marshaled fields with methods.

  2. As i already stated, structs are (almost) always passed by reference: hence the callee knows nothing about structure dimensions: what about simply leaving your additional fields to be the last ones? When calling a native function that needs your structure's pointer and the structure's size, simply lie about its size, giving the one it would have without your extra fields. I don't know if it's a legal way to marshal such a structure back when obtaining it FROM a native function. Side question: does the Marshaller process class fields marked as private? (I hope not...)

Bottali answered 22/1, 2010 at 11:12 Comment(1)
Private field are also marshaledHeads
K
-1

based on my tests, auto property like:

private int marshaled { get; set; }

will consume space while marshaling (Marshal.SizeOf)

But! explicitly specified property will not:

private int skipped
{
    get { return 0; }
    set { }
} 
Konstantin answered 8/5, 2019 at 10:19 Comment(2)
That's because your explicit property doesn't have a backing field. Fields take up space, methods and properties don't. Auto-properties have an implicit backing field.Billingsley
@ThomasLevesque you abolutely right! so silly I forgot about auto-properties backgroundKonstantin

© 2022 - 2024 — McMap. All rights reserved.