2010-08-30 49 views
0

我需要編組一個String ^的數組以調用一個需要一個BSTR數組的非託管函數。pin_ptr的陣列<Type>

在MSDN我發現文中的

How to: Marshal COM Strings Using C++ Interop

與此代碼示例:

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

所以我創建了一個新的BSTRs'陣列並稱爲元帥:StringToBSTR()爲每數組的字符串。 然後我創建了一個託管的pin_ptr數組。

array<pin_ptr<BSTR> >^ gcDummyParameters = gcnew array<pin_ptr<BSTR> >(asParameters->Length); 

但我receved錯誤:

Error 2 error C2691: 'cli::pin_ptr<Type>' : a managed array cannot have this element type 

我與本機陣列也試過:

pin_ptr<BSTR> dummyParameters[100000]; 

但即使在這種情況下,我得到了一個錯誤:

Error 1 error C2728: 'cli::pin_ptr<Type>' : a native array cannot contain this managed type 

我還能做什麼?

回答

2

微軟示例看起來很奇怪:沒有必要固定BSTR類型,因爲它是非託管的。只需創建BSTR數組並使用Marshal :: StringToBSTR填充每個成員。不要使用pin_ptr。

+0

是的,樣本片段完全是假的。只需使用BSTR數組[]。 – 2010-08-30 14:22:09

+0

http://stackoverflow.com/questions/1105010/necessary-to-pin-ptr-on-c-clr-value-types-why 讓我覺得可能有一些微軟的pin_point BSTR的晦澀理由。如果可能的話,我寧願留在安全的一面:) – sergiom 2010-08-30 14:25:02

+0

我相信Hans Passant的確認會讓你放心安全:) BSTR只是非託管指針,GC不會觸及非託管內存。否則,簡單的C++/CLI代碼就像int * p = new int [1]; * p = 1;會崩潰。 – 2010-08-30 14:46:06

2

pin_ptr應從此示例中刪除。 bs是一個局部變量,不會被垃圾收集器移動,它也會通過值傳遞給本地函數,所以如果它移動的話就不會有問題。

它指向的BSTR內容是由系統的BSTR分配器本地分配的,它也不會被垃圾收集器移動。