Come posso eseguire il marshalling di una struttura come puntatore a una struttura?
Domanda
Sto cercando di passare una struttura da C # alla libreria C ++. Passo la struttura come oggetto e la funzione C ++ lo prevede come puntatore (vuoto *).
Sto riscontrando problemi nel passare la struttura.
[DllImport("MockVadavLib.dll", CharSet = CharSet.Ansi)]
public static extern IntPtr TheFunction([MarshalAs(UnmanagedType.LPStruct)] UserRec userRec);
Ecco il testo dell'eccezione di runtime che ottengo:
" Impossibile eseguire il marshalling 'parametro # 1': combinazione di tipi gestiti / non gestiti non valida (questo tipo di valore deve essere associato a Struct). "
Anche se ho trovato un articolo MSDN che utilizza LPStruct esattamente in questo contesto.
Questa è la mia struttura che sto provando a mettere in campo:
[StructLayout(LayoutKind.Sequential)]
public struct UserRec {
[MarshalAs(UnmanagedType.I4)]
public int userParam1;
}
Questa è la funzione C ++:
MOCKVADAVLIB_API tVDACQ_CallBackRec * TheFunction(void * userParams) {...
Soluzione
Prova a passare la struttura come parametro ref.
[DllImport("MockVadavLib.dll", CharSet = CharSet.Ansi)]
public static extern IntPtr TheFunction(ref UserRec userRec);
Quando usi un ref combinato con una struttura, passa concettualmente l'indirizzo.
Altri suggerimenti
Per inciso, UnmanagedType.LPStruct
è raramente, se mai, l'argomento corretto MarshalAs
. Una citazione di Adam Nathan che è una Microsoft dipendente:
UnmanagedType.LPStruct è supportato solo per un caso specifico: trattamento di un tipo di valore System.Guid come GUID non gestito con un ulteriore livello di riferimento indiretto.