4

コアが C++ で記述され、ActiveX と .Net シェルの両方を備えたコンポーネントを移植しています。コンポーネントは、多くの場所で VARIANT 型を内部的に使用します。このコンポーネントの引数の一部のパブリック プロパティ (get/set) とメソッドは、ActiveX 実装では VARIANT 型で、.Net 実装では System::Object 型です。コードの内部では、VARIANT を直接使用しています。

VARIANT は OLE/COM 型であるため、ActiveX コンポーネントを実装するときにマーシャリングを行う必要はありませんでした。

.Net コンポーネントを実装するときは、次のようなものを使用しました。

VARIANT var;

//...

//Initialize the VARIANT value

//...


System::IntPtr p( &var );

System::Object ^o = System::Runtime::InteropServices::Marshal::GetObjectForNativeVariant(p );

return o;

WinRT では、同じような Marshal クラスはないようです。MSDN によると、「WinRT Platform::Runtime::InteropServices 名前空間は内部使用のみを目的としており、開発での使用は意図されていません。」

私のオプションは何ですか?確かに、ABI の境界を越えて VARIANT をマーシャリングする作業を行う既存のクラスが存在する必要があります。私はそのようなマーシャラーを書きたくありません。

どんな助けでも大歓迎です。

4

2 に答える 2

3

お返事をありがとうございます。Windows::Foundation::IPropertyValue を使用してユーティリティ クラスを作成することになりました。

このスレッドへのリンクとともに、コードをここに投稿しました。

WinRT コンポーネントで VARIANT をマーシャリングする

例:

// 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...

よろしく、

ロジャー

于 2012-08-20T16:43:49.033 に答える
2

Windows ランタイムには "VARIANT" に相当するものはありません。ABI レベルでは、System::Object は IInspectable を実装するオブジェクトとして表されます。これは、バリアントを置き換えるために使用できるメカニズムである可能性があります。

IReference を使用して、より高いレベルのオブジェクトを表す IInspectable ベースのインターフェイスを作成することは可能ですが、VARIANT のように弱く型付けされたセマンティクスはありません。

于 2012-08-14T14:39:09.610 に答える