Come posso ignorare un campo quando smistamento una struttura con P / Invoke
-
19-09-2019 - |
Domanda
Voglio schierare una struttura per l'uso con P / Invoke, ma questo struct contiene un campo che è rilevante solo per il mio codice gestito, quindi non voglio che sia il marshalling in quanto non appartengono alla nativa struttura. E 'anche possibile? Ero alla ricerca di un attributo simile a NonSerialized
per la serializzazione, ma non sembra esistere ...
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;
}
Ogni suggerimento sarebbe apprezzato
Soluzione
Non c'è alcun modo per rendere il CLR ignorare un campo. Vorrei invece utilizzare due strutture, e magari fare uno un membro dell'altro.
struct MyNativeStructure
{
public int foo;
public int bar;
}
struct MyStructure
{
public MyNativeStruct native;
public int ignored;
}
Altri suggerimenti
Due metodi:
-
Utilizzare una classe invece di una struttura: le strutture sono sempre passati per puntatore alla API di Windows o di altre funzioni native. Sostituzione di una chiamata a
doThis(ref myStruct)
con una chiamata adoThis([In, Out] myClass)
dovrebbe fare il trucco. Una volta fatto questo, si può semplicemente accedere ai campi non-to-be-marshalling con i metodi. -
Come ho già detto, le strutture sono (quasi) sempre passati per riferimento: da qui il chiamato non sa nulla di dimensioni della struttura: che dire semplicemente lasciare i vostri campi aggiuntivi per essere gli ultimi? Quando si chiama una funzione nativa che ha bisogno del vostro puntatore struttura e le dimensioni della struttura, semplicemente mentire sulla sua dimensione, dando quello che avrebbe senza i vostri campi aggiuntivi. Non so se è un modo legale per schierare una tale struttura indietro quando ottenerlo da una funzione nativa. domanda laterale: fa i campi della classe di processo Marshaller contrassegnati come privati? (Spero di no ...)
sulla base di mie prove, di proprietà di auto come:
private int marshaled { get; set; }
consumerà spazio, mentre marshalling (Marshal.SizeOf
)
Ma! proprietà esplicitamente specificato di non:
private int skipped
{
get { return 0; }
set { }
}