Pergunta

Gostaria de chamar minhas bibliotecas C++ não gerenciadas do meu código C#.Quais são as possíveis armadilhas e precauções que precisam ser tomadas?Obrigado pelo seu tempo.

Foi útil?

Solução

Esta questão é muito ampla.A única resposta razoável é P/Invoke, mas isso é como dizer que se você deseja programar para Windows, precisa conhecer a API Win32.

Praticamente livros inteiros foram escritos sobre P/Invoke (http://www.amazon.com/NET-COM-Complete-Interoperability-Guide/dp/067232170X) e, claro, sites inteiros foram criados: http://www.pinvoke.net/.

Outras dicas

Existem alguns caminhos que você pode seguir com isso - primeiro, você pode atualizar suas bibliotecas C++ não gerenciadas para ter um wrapper de extensões C++ gerenciadas em torno delas e fazer com que o C# utilize essas classes diretamente.Isso consome um pouco de tempo, mas fornece uma ótima ponte para código legado não gerenciado.Mas esteja ciente de que as extensões C++ gerenciadas às vezes são um pouco difíceis de navegar, pois a sintaxe é semelhante à do C++ não gerenciado, mas próxima o suficiente para que um olho muito treinado seja capaz de ver as diferenças.

O outro caminho a seguir é fazer com que seu C++ não gerenciado implemente classes COM e que o C# o utilize por meio de um assembly de interoperabilidade gerado automaticamente.Dessa forma, será mais fácil se você conhecer bem o COM.

Espero que isto ajude.

Você está descrevendo P/Invoke.Isso significa que sua biblioteca C++ precisará se expor por meio de uma interface DLL, e a interface precisará ser simples o suficiente para ser descrita para P/Invoke por meio dos atributos de chamada.Quando o código gerenciado chama o mundo não gerenciado, os parâmetros precisam ser organizados, então parece que pode haver um leve impacto no desempenho, mas você teria que fazer alguns testes para ver se o empacotamento é significativo ou não.

A maneira mais fácil de começar é certificar-se de que todas as funcionalidades do C++ sejam expostas como funções no estilo 'C'.Certifique-se de declarar a função como _stdcall.

extern "C" __declspec(dllexport) int _stdcall Foo(int a)

Certifique-se de acertar o empacotamento, especialmente coisas como ponteiros & wchar_t *.Se você errar, pode ser difícil depurar.

Depure-o de qualquer lado, mas não de ambos.Ao depurar nativo e gerenciado misto, o depurador pode ficar muito lento.Depurar um lado de cada vez economiza muito tempo.

Ser mais específico exigiria uma pergunta mais específica.

Você também pode chamar código não gerenciado via P/Invoke.Isso pode ser mais fácil se o seu código não usar COM no momento.Eu acho que você provavelmente precisaria escrever alguns pontos de exportação específicos em seu código usando ligações "C" se seguisse esse caminho.

Provavelmente, a maior coisa que você deve observar em minha experiência é que a falta de coleta de lixo determinística significa que seus destruidores não serão executados quando você pensava que seriam executados anteriormente.Você precisa ter isso em mente e usar IDisposable ou algum outro método para garantir que seu código gerenciado seja limpo quando você desejar.

É claro que sempre existe o PInvoke por aí se você empacotar seu código como DLLs com pontos de entrada externos.Nenhuma das opções é indolor.Eles dependem de a) sua habilidade em escrever wrappers COM ou Managed C b) arriscar seu braço no PInvoke.

eu daria uma olhada gole, usamos isso com bons resultados em nosso projeto para expor nossa API C++ a outras plataformas de linguagem.

É um projeto bem mantido que efetivamente cria um wrapper fino em torno de sua biblioteca C++ que pode permitir que linguagens como C# se comuniquem diretamente com seu código nativo - evitando o trabalho de implementar (e depurar) código cola.

Se você quiser bons exemplos de PInvoke, você pode dar uma olhada PInvoke.net.Ele contém exemplos de como chamar a maioria das funções da API do Win.

Além disso, você pode usar a ferramenta deste artigo Clr de dentro para fora:PInvoke isso traduzirá seu arquivo .h para wrappers c#.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top