2

Platform::StringReferenceconst wchar_t*コピーを作成せずにa を受け入れる関数に ABI 境界を越えてa を渡すことができるように存在しString^ます。は、内部ポインタが元の と一致するStringReferenceに暗黙的に変換されます。これは、次のコードによって検証されます。ステップスルーすると、次のことがわかります。String^const wchar_t*pz == z

void param(String^ s)
{
    const wchar_t* z = s->Data();
}

App::App()
{
    std::wstring p = L"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz";
    const wchar_t* pz = p.c_str();
    param(StringReference(pz));
}

ただし、 a を返そうとしてStringReferenceも同じようには機能しないようで、その理由が気になります。返す関数があり、そこからString^a を返すStringReference場合、同じ暗黙の変換演算子が呼び出されますが、呼び出し元がそれらを取得するString^と、コピーを含む別の内部データ ポインターがあります。これを試すコードは次のとおりです。

String^ ret()
{
    std::wstring s = L"12345678901234567890123456789012345678901234567890";
    const wchar_t* z = s.c_str();
    return StringReference(z);
}

App::App()
{
    String^ r = ret();
    const wchar_t* rz = r->Data();
}

そのコードは 2 つの方法で検証します。1 つ目はステップスルーするz != rzと、2 つ目rはガベージではなく有効な文字列を指すことになるため、コピーが作成されたに違いありません。元の文字列は の最後で解放されるためですret

また、out パラメーターを介して返そうとしましたが、ストレート リターンと同じ結果が得られます (有効な文字列z != ozo終了します)。

void out(String^* r)
{
    std::wstring s = L"12345678901234567890123456789012345678901234567890";
    const wchar_t* z = s.c_str();
    *r = StringReference(z);
}

App::App()
{
    String^ o;
    out(&o);
    const wchar_t* oz = o->Data();
}

StringReference渡すことができるのと同じ方法で、ABI 境界を越えてa を返す方法はありますか? 動作は、呼び出し元の言語と、その言語が WinRT から文字列をマーシャリングする方法に依存すると思いますが、少なくとも C++/CX 呼び出し元はそれを実行できるはずです。

4

1 に答える 1