Partilhar via


Usando Interoperabilidade C++ (PInvoke implícito)

Ao contrário de outras linguagens .NET, o Visual C++ tem suporte à interoperabilidade que permite que o código gerenciado e não gerenciado exista no mesmo aplicativo e até mesmo no mesmo arquivo (com os pragmas gerenciados e não gerenciados ). Isso permite que os desenvolvedores do Visual C++ integrem a funcionalidade .NET em aplicativos existentes do Visual C++ sem perturbar o restante do aplicativo.

Você também pode chamar funções não gerenciadas de uma compilação gerenciada usando dllexport, dllimport.

PInvoke implícito é útil quando não é necessário especificar como os parâmetros da função serão organizados, ou qualquer um dos outros detalhes que podem ser definidos ao chamar explicitamente DllImportAttribute.

O Visual C++ fornece duas maneiras para funções gerenciadas e não gerenciadas interoperarem:

O PInvoke explícito é suportado pelo .NET Framework e está disponível na maioria das linguagens .NET. Mas, como o próprio nome indica, C++ Interop é específico para Visual C++.

Interoperabilidade C++

C++ Interop fornece melhor segurança de tipo, e normalmente é menos tedioso de implementar. No entanto, a Interoperabilidade C++ não é uma opção se o código-fonte não gerenciado não estiver disponível ou para projetos entre plataformas.

Interoperabilidade COM C++

Os recursos de interoperabilidade suportados pelo Visual C++ oferecem uma vantagem particular sobre outras linguagens .NET quando se trata de interoperar com componentes COM. Em vez de ser limitado às restrições do .NET Framework Tlbimp.exe (Type Library Importer), como suporte limitado para tipos de dados e a exposição obrigatória de cada membro de cada interface COM, o C++ Interop permite que os componentes COM sejam acessados à vontade e não requer assemblies de interoperabilidade separados. Ao contrário do Visual Basic e C#, Visual C++ pode usar objetos COM diretamente usando os mecanismos COM usuais (como CoCreateInstance e QueryInterface). Isso é possível devido aos recursos de interoperabilidade C++ que fazem com que o compilador insira automaticamente o código de transição para passar de funções gerenciadas para não gerenciadas e vice-versa.

Usando a interoperabilidade C++, os componentes COM podem ser usados como normalmente são usados ou podem ser encapsulados dentro de classes C++. Essas classes de invólucro são chamadas de invólucros executáveis em tempo de execução personalizados, ou CRCWs, e têm duas vantagens sobre o uso do COM diretamente no código da aplicação.

  • A classe resultante pode ser usada de linguagens diferentes do Visual C++.

  • Os detalhes da interface COM podem ser ocultos do código do cliente gerenciado. Os tipos de dados .NET podem ser usados no lugar de tipos nativos, e os detalhes do empacotamento de dados podem ser executados de forma transparente dentro do CRCW.

Independentemente de COM ser usado diretamente ou por meio de um CRCW, tipos de argumento diferentes de tipos simples e blittable (não convertíveis de forma automática) devem ser marshalizados.

Tipos Blittable

Para APIs não gerenciadas que usam tipos simples e intrínsecos (consulte Tipos Blittable e Non-Blittable), nenhuma codificação especial é necessária porque esses tipos de dados têm a mesma representação na memória, mas tipos de dados mais complexos exigem empacotamento de dados explícito. Para obter um exemplo, consulte Como: Chamar DLLs nativas usando PInvoke a partir de código gerido.

Exemplo

// vcmcppv2_impl_dllimp.cpp
// compile with: /clr:pure user32.lib
using namespace System::Runtime::InteropServices;

// Implicit DLLImport specifying calling convention
extern "C" int __stdcall MessageBeep(int);

// explicit DLLImport needed here to use P/Invoke marshalling because
// System::String ^ is not the type of the first parameter to printf
[DllImport("msvcrt.dll", EntryPoint = "printf", CallingConvention = CallingConvention::Cdecl,  CharSet = CharSet::Ansi)]
// or just
// [DllImport("msvcrt.dll")]
int printf(System::String ^, ...);

int main() {
   // (string literals are System::String by default)
   printf("Begin beep\n");
   MessageBeep(100000);
   printf("Done\n");
}
Begin beep
Done

Na presente seção

Para obter informações sobre como usar delegados em um cenário de interoperabilidade, consulte delegate (C++ Component Extensions).

Ver também