如何:使用 C++ Interop 封送處理 COM 字串

本主題示範如何將 BSTR(COM 程式設計中偏好的基底字元串格式)從 Managed 傳遞至 Unmanaged 函式,反之亦然。 如需與其他字串類型交互操作,請參閱下列主題:

下列程式碼範例會使用 Managed、Unmanaged #pragma 指示詞,在相同的檔案中實作 Managed 和 Unmanaged 函式,但如果在個別檔案中定義,這些函式會以相同方式交互操作。 僅包含 Unmanaged 函式的檔案不需要使用 /clr 進行編譯(Common Language Runtime 編譯)。

範例:將 BSTR 從 Managed 傳遞至 Unmanaged 函式

下列範例示範如何將 BSTR(COM 程式設計中使用的字串格式)從 Managed 傳遞至 Unmanaged 函式。 呼叫的 Managed 函式會使用 StringToBSTR 來取得 .NET System.String 內容的 BSTR 標記法位址。 此指標是使用 pin_ptr #C++/CLI 釘 選,以確保其實體位址不會在 Unmanaged 函式執行期間于垃圾收集週期期間變更。 禁止垃圾收集行程移動記憶體,直到 pin_ptr (C++/CLI) 超出範圍為止。

// 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);
}

範例:將 BSTR 從 Unmanaged 傳遞至 Managed 函式

下列範例示範如何將 BSTR 從 Unmanaged 傳遞至 Managed 函式。 接收的 Managed 函式可以使用 中的字串作為 BSTR,或使用 PtrToStringBSTR 將它 String 轉換成 ,以便與其他 Managed 函式搭配使用。 由於代表 BSTR 的記憶體是在 Unmanaged 堆積上配置,因此不需要釘選,因為 Unmanaged 堆積上沒有垃圾收集。

// 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();
}

另請參閱

使用 C++ Interop (隱含 PInvoke)