Dela via


Använda C++ Interop (implicit PInvoke)

Till skillnad från andra .NET-språk har Visual C++ samverkansstöd som gör att hanterad och ohanterad kod kan finnas i samma program och även i samma fil (med den hanterade, ohanterade pragmasen). På så sätt kan Visual C++-utvecklare integrera .NET-funktioner i befintliga Visual C++-program utan att störa resten av programmet.

Du kan också anropa ohanterade funktioner från en hanterad kompilering och använda dllexport, dllimport.

Implicit PInvoke är användbart när du inte behöver ange hur funktionsparametrar ska konverteras, eller någon annan information som kan anges när du uttryckligen anropar DllImportAttribute.

Visual C++ tillhandahåller två sätt för hanterade och ohanterade funktioner att samverka:

Explicit PInvoke stöds av .NET Framework och är tillgängligt på de flesta .NET-språk. Men som namnet antyder är C++ Interop specifikt för Visual C++.

C++ Interop

C++ Interop ger bättre typsäkerhet, och det är vanligtvis mindre omständligt att implementera. C++ Interop är dock inte ett alternativ om den ohanterade källkoden inte är tillgänglig eller för plattformsoberoende projekt.

C++ COM Interop

Samverkansfunktionerna som stöds av Visual C++ ger en särskild fördel jämfört med andra .NET-språk när det gäller samverkan med COM-komponenter. I stället för att begränsas till begränsningarna för .NET Framework -Tlbimp.exe (typbiblioteksimportör), till exempel begränsat stöd för datatyper och obligatorisk exponering för varje medlem i varje COM-gränssnitt, tillåter C++ Interop att COM-komponenter kan nås efter behov och kräver inte separata interop-sammansättningar. Till skillnad från Visual Basic och C# kan Visual C++ använda COM-objekt direkt med hjälp av vanliga COM-mekanismer (till exempel CoCreateInstance och QueryInterface). Detta är möjligt på grund av C++ Interop-funktioner som gör att kompilatorn automatiskt infogar övergångskoden för att gå från hanterade till ohanterade funktioner och tillbaka igen.

Med C++ Interop kan COM-komponenter användas eftersom de används normalt eller omslutas i C++-klasser. Dessa omslutningsklasser kallas anpassade runtime-anropsbara omslutningar eller CRCW:er, och de har två fördelar jämfört med att använda COM direkt i programkoden:

  • Den resulterande klassen kan användas från andra språk än Visual C++.

  • Information om COM-gränssnittet kan döljas från den hanterade klientkoden. .NET-datatyper kan användas i stället för interna typer och information om datamarsering kan utföras transparent i CRCW.

Oavsett om COM används direkt eller via en CRCW måste andra argumenttyper än enkla, blittable-typer konverteras.

Blittable-typer

För ohanterade API:er som använder enkla, inbyggda typer (se Blittable- och Non-Blittable Types) krävs ingen särskild kodning eftersom dessa datatyper har samma representation i minnet, men mer komplexa datatyper kräver explicit datamarsering. Ett exempel finns i Så här anropar du interna DLL:er från hanterad kod med hjälp av PInvoke.

Exempel

// 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

I det här avsnittet

Information om hur du använder ombud i ett interop-scenario finns i ombud (C++-komponenttillägg).

Se även