Domanda

Ho una raccolta di terze parti di file .h insieme ai file .lib che li accompagnano. Sto avvolgendo quei file C ++ nativi con un wrapper C ++ / CLI e sto effettuando le chiamate finali da C #. Ho un problema quando chiamo metodi che prevedono il passaggio di un riferimento in cui il valore non viene modificato nel mio wrapper a meno che non lo cambi esplicitamente.

Il mio codice wrapper C ++ / CLI al momento è simile al seguente:

bool get_testInt16(int16% testInt16)
{
   int16* t = static_cast<int16*>(GCHandle::ToIntPtr(GCHandle::Alloc(testInt16)).ToPointer());
   bool b = m_NativeCMTY_TestData->get_testInt16(*t);
   testInt16 = *t;
   return b;
};

E il corrispondente codice C ++ nativo assomiglia a:

bool get_testInt16(int16 &testInt16);

Immagino che ci debba essere un modo migliore, ma forse no? Diciamo solo che SPERANO che c'è un modo migliore!

È stato utile?

Soluzione

Un'opzione sarebbe fare:

bool get_testInt16(int16% testInt16)
{
   int16 t = testInt16;
   bool b = m_NativeCMTY_TestData->get_testInt16(t);
   testInt16 = t;
   return b;
};

Quindi semplicemente crei una variabile nativa locale ed eviti l'enorme roba di cast e puntatore .NET.

Altri suggerimenti

qualsiasi motivo per cui non stai utilizzando i puntatori di blocco invece di GCHandle :: ToIntPtr (GCHandle :: Alloc (testInt16)). ToPointer () ?

Anche il blocco del valore di riferimento in questo modo è troppo tardi.

Se il riferimento è a un valore di stack non è necessario, se è un riferimento a un campo di istanza, il codice chiamante dovrebbe davvero bloccare l'oggetto (anche se si tratta di una perdita disordinata di semantica non gestita nel codice gestito che almeno rende il comportamento del metodo è chiaro.

Dal momento che il parametro ref è così piccolo, sarebbe logico evitare completamente tutti gli appuntamenti e crearne uno temporaneo nello stack, passarlo alla funzione non gestita e quindi riscriverlo nell'originale.

bool get_testInt16(int16% testInt16)
{
   int16 temp = testInt16;
   bool b = m_NativeCMTY_TestData->get_testInt16(temp);
   testInt16 = temp;
   return b;
};
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top