问题
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
回答1:
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;
}
回答2:
Two methods:
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 todoThis([In, Out] myClass)
should do the trick. Once you've done this, you can simply access your not-to-be-marshaled fields with methods.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...)
回答3:
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 { }
}
来源:https://stackoverflow.com/questions/1704282/how-can-i-ignore-a-field-when-marshalling-a-structure-with-p-invoke