2010-08-30 33 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分配器本地分配的,它也不会被垃圾收集器移动。