我在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.
这是什么原因?这是预期的行为还是一个错误?
答案 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”部分。