为什么wchar_t *的第一个字符在传递给WinRT组件时会被删除?

时间:2013-06-13 10:50:25

标签: c++ windows-runtime interop

我在WinRT组件中有一个ref类:

namespace WinRTComponent
{
    public ref class Class1 sealed
    {
    public:
        Class1();

        void MyMethod(wchar_t* wcharPtr)
        {
            // Do nothing.
        }
    };
}

我还有一个Windows Store C ++ XAML应用程序,它引用了WinRT组件。在我的应用程序中,我运行以下代码:

std::wstring str = L"Some text.";
const wchar_t* strPtr = str.data();

WinRTComponent::Class1^ class1 = ref new WinRTComponent::Class1();

wchar_t firstCharBefore = strPtr[0]; // It is 'S', correctly.

class1->MyMethod(const_cast<wchar_t*>(strPtr));

wchar_t firstCharAfter = strPtr[0]; // It is 0! Why?

当我将wchar_t *指针传递给WinRT组件的公共方法时,字符串的第一个字符将被删除并更改为0.

这是什么原因?这是预期的行为还是一个错误?

1 个答案:

答案 0 :(得分:2)

我认为这是因为void MyMethod(wchar_t* wcharPtr)上的公共方法ref class不是一个接受输入字符串的函数,它是一个具有wchar_t out参数的函数。换句话说,WinRT MyMethod是一个返回16位字符的函数。所以我的猜测是,WinRT ABI机制要么在将它提供给MyMethod之前消除该值,要么检测到MyMethod的实现从未分配给它并生成为其分配默认值的代码

关键点是,ref class的公共方法上的指针参数意味着输出,而不是指针输入。指针不能跨越ABI边界,只有WinRT类型可以。 C ++类型wchar_t映射到WinRT 16位字符类型,所以它没关系,指针参数是C ++ / CX实现WinRT输出参数的方式,因为这是C ++通过参数返回数据的最自然方式。 / p>

要编写在C ++ / CX中采用字符串输入值的组件的公共方法,必须使用Platform::String^作为参数类型。如果从C ++ / CX调用此函数,则可以通过传递StringReference

来避免复制
WinRTComponent::Class1^ class1 = ref new WinRTComponent::Class1();
class1->MyMethod(Platform::StringReference(strPtr));

如果你这样做,你应该会发现在Data() String^内拨打MyMethod可以获得与你传入的strPtr相同的内容。

有关详细信息,请参阅C++/CX strings documentation的“StringReference”部分。