Freigeben über


Gewusst wie: Marshallen von COM-Zeichenfolgen mit C++-Interop

In diesem Thema wird beschrieben, wie BSTR (das bei der COM-Programmierung bevorzugte grundlegende Zeichenfolgenformat) von einer verwalteten an eine nicht verwaltete Funktion und umgekehrt übergeben werden kann.Informationen zur Interoperation mit anderen Zeichenfolgentypen finden Sie in den folgenden Themen:

In den folgenden Codebeispielen werden die verwaltet, nicht verwaltet-#pragma-Direktiven verwendet, um verwaltete und nicht verwaltete Funktionen in derselben Datei zu implementieren. Diese Funktionen arbeiten jedoch auf dieselbe Weise zusammen, wenn sie in separaten Dateien definiert werden.Dateien, die ausschließlich nicht verwaltete Funktionen enthalten, müssen nicht mit /clr (Common Language Runtime-Kompilierung) kompiliert werden.

Beispiel

Das folgende Beispiel zeigt, wie BSTR (ein in der COM-Programmierung verwendetes Zeichenfolgenformat) von einer verwalteten an eine nicht verwaltete Funktion übergeben werden kann.Die aufrufende verwaltete Funktion verwendet StringToBSTR zum Abrufen der Adresse einer BSTR-Darstellung der Inhalte eines .NET-System.String.Dieser Zeiger wird mit pin_ptr fixiert, um sicherzustellen, dass seine physische Adresse während eines Garbage Collection-Zyklus bei Ausführung einer nicht verwalteten Funktion nicht geändert wird.Der Garbage Collector kann so lange keinen Arbeitsspeicher verschieben, bis pin_ptr den Bereich verlassen hat.

// MarshalBSTR1.cpp
// compile with: /clr
#define WINVER 0x0502
#define _AFXDLL
#include <afxwin.h>

#include <iostream>
using namespace std;

using namespace System;
using namespace System::Runtime::InteropServices;

#pragma unmanaged

void NativeTakesAString(BSTR bstr) {
   printf_s("%S", bstr);
}

#pragma managed

int main() {
   String^ s = "test string";

   IntPtr ip = Marshal::StringToBSTR(s);
   BSTR bs = static_cast<BSTR>(ip.ToPointer());
   pin_ptr<BSTR> b = &bs;

   NativeTakesAString( bs );
   Marshal::FreeBSTR(ip);
}

Das folgende Beispiel zeigt, wie eine BSTR-Zeichenfolge von einer nicht verwalteten an eine verwaltete Funktion übergeben werden kann.Die empfangende verwaltete Funktion kann entweder die Zeichenfolge als BSTR in verwenden oder PtrToStringBSTR verwenden, um es zu String für die Verwendung mit anderen verwalteten Funktionen zu konvertieren.Da der BSTR darstellende Arbeitsspeicher auf dem nicht verwalteten Heap belegt ist, ist keine Fixierung erforderlich, denn auf dem nicht verwalteten Heap erfolgt keine Garbage Collection.

// MarshalBSTR2.cpp
// compile with: /clr
#define WINVER 0x0502
#define _AFXDLL
#include <afxwin.h>

#include <iostream>
using namespace std;

using namespace System;
using namespace System::Runtime::InteropServices;

#pragma managed

void ManagedTakesAString(BSTR bstr) {
   String^ s = Marshal::PtrToStringBSTR(static_cast<IntPtr>(bstr));
   Console::WriteLine("(managed) convered BSTR to String: '{0}'", s);
}

#pragma unmanaged

void UnManagedFunc() {
   BSTR bs = SysAllocString(L"test string");
   printf_s("(unmanaged) passing BSTR to managed func...\n");
   ManagedTakesAString(bs);
}

#pragma managed

int main() {
   UnManagedFunc();
}

Siehe auch

Referenz

Verwenden von C++-Interop (implizites PInvoke)