Pergunta

Estou tentando entender minhas opções para chamar uma implementação de biblioteca C# do C ++ não gerenciado.

Meu módulo de nível superior é um C ++ COM/ATL DLL não gerenciado. Eu gostaria de integrar a funcionalidade de uma DLL C# gerenciada existente. Eu tenho e posso recompilar a fonte de ambas as bibliotecas.

Eu entendo por ler artigos como Esta visão geral no msdn e isso é tão pergunta que pode ser possível criar uma DLL de "modo misto", que permite que o código C ++ nativo seja chamado para a biblioteca C#.

Eu tenho algumas perguntas sobre essa abordagem:

  1. Como faço para configurar isso? Posso simplesmente alterar algumas propriedades no projeto COM/ATL existente para permitir o uso dos módulos C#?
  2. Como essas chamadas de modo misto diferem no desempenho das chamadas de interoperamento COM? Existe um formato de string comum que pode ser usado para evitar conversão ou cópias profundas entre os módulos?
  3. Se essa DLL for criada em modo misto, ainda poderá ser interface/usada da mesma maneira por seus clientes COM, ou eles precisam estar cientes do modo misto?
  4. A inclusão do CLR imporá uma sobrecarga substancial ao carregar esse objeto COM?

Sou novo no desenvolvimento do Windows, por isso, comente se alguma coisa na declaração de pergunta precisar de esclarecimento ou correção.

Desde já, obrigado.

Foi útil?

Solução

Como faço para configurar isso? Posso simplesmente alterar algumas propriedades no projeto COM/ATL existente para permitir o uso dos módulos C#?

Se você controlar completamente esse projeto, alterar essas configurações não é um problema, com certeza. Tudo que você precisa é ativar /clr Para este projeto (nas propriedades do projeto, abra a página "Geral" e procure o suporte "Common Language RunTime"). Agora você pode usar alças gerenciadas (^) e outros bits C ++/CLI em seu projeto, conforme necessário. Todo o código existente escrito no C ++ simples deve continuar funcionando (ele será compilado para o MSIL agora, na medida possível, mas sua semântica permanecerá inalterada).

Como essas chamadas de modo misto diferem no desempenho das chamadas de interoperamento COM? Existe um formato de string comum que pode ser usado para evitar conversão ou cópias profundas entre os módulos?

Uma chamada de modo misto será mais rápido, porque usa convenções de chamadas mais rápidas e não faz nenhum agendamento da maneira como a Com a interop (você usa tipos inerentemente compatíveis ou faz suas próprias conversões explícitas).

Não há formato de string comum - o problema é que System::String Aloca e possui seu buffer, e também exige que ele seja imutável; Então você não pode criar um buffer e depois envolvê -lo como String, ou criar um String e depois use -o como um buffer para produzir texto para.

Se essa DLL for criada em modo misto, ainda poderá ser interface/usada da mesma maneira por seus clientes COM, ou eles precisam estar cientes do modo misto?

Pode ser a mesma interface, mas se for inserido por meio de um ponto de entrada nativo, tentará carregar o CLR no processo, a menos que alguém já esteja carregado. Se o cliente de chamada já tivesse carregado o CLR antes da chamada (ou o próprio cliente foi chamado do código gerenciado), você receberá o CLR que já está carregado, o que pode ser diferente do CLR que seu código exige (por exemplo, cliente pode ter carregado 1.1 e seu código precisa de 2.0).

A inclusão do CLR imporá uma sobrecarga substancial ao carregar esse objeto COM?

Depende do que você define por cima. Tamanho do código? Penalidades no tempo de execução? Pegada de memória?

De qualquer forma, carregar o CLR significa que você obtém todas as máquinas GC e JIT. Esses não são baratos. Dito isto, se você precisar ligar para o código gerenciado em última análise, não há como contornar isso - você vai tenho Para carregar o CLR em algum processo para fazer isso. As penalidades não vão diferir entre os conjuntos de interope com COM e o modo misto C ++/CLI.

Outras dicas

Não posso dizer muito sobre os detalhes como, por exemplo, os problemas de string, já que nunca usei ativamente essa abordagem.

Mas você pode consumir facilmente qualquer interface com a partir de qualquer código C#, simplesmente deixando um assistente VS criar um proxy para você, não há sobrecarga de desempenho, exceto o que você sempre tem ao invocar com e .net.

A outra direção, você só precisa definir seus assemblies c# ' ComVisibleAttribute Para true (no VS, é uma caixa de seleção simples nas propriedades do projeto) e, em seguida, o compilador criará automaticamente interfaces com você. Novamente, não há penalidade de desempenho adicional.

HTH!

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