如何:使用 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();
}