Utilizar la interoperabilidad de C++ (PInvoke implícito)
A diferencia de otros lenguajes de .NET, Visual C++ cuenta con compatibilidad de interoperabilidad, que permite que haya código administrado y no administrado en la misma aplicación, e incluso en el mismo archivo (con los pragmas managed, unmanaged). De este modo, los desarrolladores de Visual C++ pueden integrar la funcionalidad de .NET en las aplicaciones de Visual C++ existentes sin que esto afecte al resto de la aplicación.
También se pueden efectuar llamadas a funciones no administradas desde una operación de compilación administrada utilizando dllexport, dllimport.
PInvoke implícito es útil cuando no es necesario especificar cómo se van a calcular referencias en los parámetros de una función, o cualquiera de los otros detalles se puede especificar cuando se llama explícitamente a DllImportAttribute.
Visual C++ proporciona dos formas de interoperabilidad para las funciones administradas y no administradas:
.NET Framework admite PInvoke explícito, que está disponible en la mayoría de los lenguajes de .NET. Pero, como su propio nombre indica, la interoperabilidad de C++ es específica de Visual C++.
Interoperabilidad de C++
La interoperabilidad de C++ es preferible a PInvoke explícito porque proporciona mejor seguridad de tipos, suele ser menos tediosa de implementar, es más tolerable a las modificaciones de la API no administrada y permite mejoras en el rendimiento que no son posibles con PInvoke explícito. Sin embargo, la interoperabilidad de C++ no es posible si el código fuente no administrado no está disponible o al compilar con /clr:safe (vea Código puro y comprobable (C++/CLI) para obtener más información).
Interoperabilidad COM de C++
Las características de interoperabilidad admitidas por Visual C++ suponen una ventaja concreta con respecto a otros lenguajes de .NET en lo que se refiere a la interoperabilidad con componentes COM. En lugar de limitarse a las restricciones de TlbImp.exe (Importador de la biblioteca de tipos) de .NET Framework, como la compatibilidad limitada para tipos de datos y la exposición obligada de cada miembro de cada interfaz COM, la interoperabilidad de C++ permite el acceso a voluntad a componentes COM y no requiere ensamblados de interoperabilidad independientes. Para obtener más información, vea Utilizar servidores COM nativos de .NET.
Tipos representables como bits o bytes
Para API no administradas que usan tipos intrínsecos simples (vea Tipos que pueden o que no pueden representarse como bits o bytes), no se requiere una codificación especial porque estos tipos de datos tienen la misma representación en memoria, pero tipos de datos más complejos requieren cálculo de referencias de datos explícito. Para obtener un ejemplo, vea Cómo: Llamar a archivos DLL nativos desde el código administrado mediante PInvoke.
Ejemplo
// 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");
}
En esta sección
Cómo: Calcular referencias de cadenas ANSI mediante la interoperabilidad de C++
Cómo: Calcular referencias de cadenas Unicode mediante la interoperabilidad de C++
Cómo: Calcular referencias de cadenas COM mediante la interoperabilidad de C++
Cómo: Calcular referencias de estructuras mediante la interoperabilidad de C++
Cómo: Calcular referencias de matrices mediante la interoperabilidad de C++
Cómo: Calcular referencias de punteros incrustados mediante la interoperabilidad de C++
Cómo: Cargar recursos no administrados en una matriz de bytes
Cómo: Modificar la clase de referencia en una función nativa
Cómo: Agregar un archivo DLL nativo a la Caché de ensamblados global
Cómo: Mantener la referencia a un tipo de valor en un tipo nativo
Cómo: Mantener una referencia a objeto en la memoria no administrada
Para obtener información sobre cómo utilizar delegados en un escenario de interoperabilidad, vea delegate.