Melhor maneira de passar por referência de C# para C ++?
-
11-07-2019 - |
Pergunta
Eu tenho uma coleção de arquivos .h de terceiros, juntamente com os arquivos .lib que os acompanham. Estou envolvendo esses arquivos C ++ nativos com um invólucro C ++/CLI e fazendo chamadas finais de C#. Tenho um problema quando chamo métodos que esperam que uma referência seja passada onde o valor não está sendo alterado no meu invólucro, a menos que eu o altere explicitamente.
Meu código de invólucro C ++/CLI atualmente se parece com o seguinte:
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 o código C ++ nativo correspondente se parece:
bool get_testInt16(int16 &testInt16);
Eu acho que tem que haver uma maneira melhor, mas talvez não? Diga apenas que espero que haja uma maneira melhor!
Solução
Uma opção seria fazer:
bool get_testInt16(int16% testInt16)
{
int16 t = testInt16;
bool b = m_NativeCMTY_TestData->get_testInt16(t);
testInt16 = t;
return b;
};
Então, você simplesmente cria uma variável nativa local e evita o enorme elenco e as coisas do ponteiro .NET.
Outras dicas
qualquer motivo que você não esteja usando ponteiros em vez de GCHandle::ToIntPtr(GCHandle::Alloc(testInt16)).ToPointer()
?
Também fixando o valor referenciado como esse é tarde demais.
Se a referência for a um valor de pilha, é desnecessário, se for uma referência a um campo de instância, o código de chamada deve realmente fixar o objeto (embora este seja um vazamento bagunçado de semntações não gerenciadas no código gerenciado, pelo menos faz o comportamento de o método claro.
Como o parâmetro REF é tão pequeno, faria sentido evitar toda a fixação completamente e criar uma temporária na pilha, passar até a função não gerenciada e, em seguida, escrevê -la de volta ao original.
bool get_testInt16(int16% testInt16)
{
int16 temp = testInt16;
bool b = m_NativeCMTY_TestData->get_testInt16(temp);
testInt16 = temp;
return b;
};