array of pin_ptr<Type>
I need to marshal an array of String^ to call a unmanaged function that expects an array of BSTRs.
On MSDN I found the article
How to: Marshal COM Strings Using C++ Interop
with this code sample:
// 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);
}
So I created a new BSTRs' array and called the Marshal::StringToBSTR() for every String of the array. Then I created a managed pin_ptr array.
array<pin_ptr<BSTR> >^ gcDummyParameters = gcnew array<pin_ptr<BSTR> >(asParameters->Length);
but I receved the error:
Error 2 error C2691: 'cli::pin_ptr<Type>' : a managed array cannot have this element type
I tried a开发者_高级运维lso with a native array:
pin_ptr<BSTR> dummyParameters[100000];
but even in this case I got an error:
Error 1 error C2728: 'cli::pin_ptr<Type>' : a native array cannot contain this managed type
What else can I do?
Microsoft sample looks strange: there is no need to pin BSTR type because it is unmanaged. Just create BSTR array and fill every member using Marshal::StringToBSTR. Don't use pin_ptr.
pin_ptr should be removed from this sample. bs is a local variable and will not be moved by the garbage collector, also it is passed to the native function by value so there would be no problem if it did move.
The BSTR content to which it points is natively allocated by the system's BSTR allocator, it also will not be moved by the garbage collector.
精彩评论