我正在移植我们的组件,该组件的核心是用C++编写的,并且具有ActiveX和.Net shell。该组件在内部的许多地方使用 VARIANT 类型。此组件参数的某些公共属性(get/set)和方法在 ActiveX 实现中属于 VARIANT 类型,在 .Net 实现中属于 System::Object 类型。在我们的代码内部,我们直接使用 VARIANT 。
在实现 ActiveX 组件时,我不需要执行任何封送处理,因为 VARIANT 是 OLE/COM 类型。
在实现 .Net 组件时,我使用了类似于以下内容:
VARIANT var;
//...
//Initialize the VARIANT value
//...
System::IntPtr p( &var );
System::Object ^o = System::Runtime::InteropServices::Marshal::GetObjectForNativeVariant(p );
return o;
在WinRT中,似乎没有任何类似的元帅类可以完成这项工作。根据MSDN"WinRT Platform::Runtime::InteropServices命名空间仅供内部使用,不用于开发。
我有哪些选择?当然,必须有一个现有的类来完成跨 ABI 边界编组 VARIANT 的工作。我不想写这样的编组器,然后发现它已经存在了!
任何帮助将不胜感激。
感谢您的回复。我最终使用Windows::Foundation::IPropertyValue编写了一个实用程序类。
我在这里发布了代码以及返回此线程的链接:
在 WinRT 组件中封送变体
例:
// in a C# we can write:
string [] sarray = new string[2];
sarray[0] = "abc";
sarray[1] = "def";
SetValue(sarray);
//in C++/CX we write:
void SetValue( Object ^value )
{
VARIANT var;
VariantInit( &var );
var = acMarshall::MarshalObjectToVariant( value );
//
// We will have a SAFEARRAY of BSTRs in the VARIANT...
//
VariantClear( &var );
}
// and the reverse, in C++/CX
Object ^ GetValue()
{
VARIANT var;
VariantInit(&var);
v.vt = VT_BSTR | VT_ARRAY;
SAFEARRAYBOUND sab;
sab.cElements = 2;
sab.lLbound = 0;
SAFEARRAY *psa = SafeArrayCreate( VT_BSTR, 1, &sab );
LPVOID p = NULL;
SafeArrayAccessData( psa, &p );
((BSTR *) p)[0] = SysAllocString(L"string one");
((BSTR *) p)[1] = SysAllocString(L"string two");
SafeArrayUnaccessData( psa );
var.parray = psa;
Object ^ obj = acMarshall::MarshalVariantToObject( var );
VariantClear( &var );
return obj;
}
//and in C#:
object obj = GetValue() //obj will contain a string array...
问候
知道了
在 Windows 运行时中没有"VARIANT"等效项。 在 ABI 级别,System::Object 表示为实现 IInspectable 的对象,这可能是可用于替换变体的机制。
可以使用IReference 创建一个基于 IInspectable 的接口,该接口表示您的高级对象,但它不会具有 VARIANT 那样的弱类型语义。