我需要编组一个String ^数组来调用一个需要BSTR数组的非托管函数。
在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'数组,并为数组的每个String调用Marshal :: StringToBSTR()。 然后我创建了一个托管的pin_ptr数组。
array<pin_ptr<BSTR> >^ gcDummyParameters = gcnew array<pin_ptr<BSTR> >(asParameters->Length);
但我收到了错误:
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
我还能做什么?
答案 0 :(得分:2)
Microsoft示例看起来很奇怪:没有必要固定BSTR类型,因为它是不受管理的。只需创建BSTR数组并使用Marshal :: StringToBSTR填充每个成员。不要使用pin_ptr。
答案 1 :(得分:2)
pin_ptr。 bs是一个局部变量,不会被垃圾收集器移动,它也会按值传递给本机函数,因此如果移动它就没有问题。
它所指向的BSTR内容由系统的BSTR分配器本地分配,它也不会被垃圾收集器移动。