Megosztás a következőn keresztül:


Sztringkezelés a C++/WinRT-ben

A C++/WinRTa Windows Futtatókörnyezet API-jait a C++ Standard Könyvtár széles karakterlánctípusokkal hívhatja meg, például std::wstring (megjegyzés: nem keskeny karakterlánctípusokkal, például std::string). A C++/WinRT egyéni sztringtípusa winrt::hstring (a C++/WinRT alapkódtárban van definiálva, amely %WindowsSdkDir%Include\<WindowsTargetPlatformVersion>\cppwinrt\winrt\base.h). Ez az a sztringtípus, amelyet a Windows Futtatókörnyezet konstruktorai, függvényei és tulajdonságai ténylegesen vesznek és ad vissza. Sok esetben azonban – köszönhetően konverziós konstruktorainak és konverziós operátorainak – választhat, hogy figyelembe veszi-e az ügyfélkódban vagy sem. Ha API-kat fejleszt, akkor nagyobb valószínűséggel kell tudnia a hstring-ről.

A C++-ban számos sztringtípus létezik. Az std::basic_string mellett számos kódtárban léteznek változatok. A C++17 sztringkonvertálási segédprogramokkal és std::basic_string_view rendelkezik az összes sztringtípus közötti rések áthidalásához. winrt::hstring átalakíthatóságot biztosít a(z) std::wstring_view számára, hogy elérje azt az interoperabilitást, amelyre az std::basic_string_view készült.

Uri használata a std::wstring (és opcionálisan a winrt::hstring) alkalmazásával

A(z) Windows::Foundation::Uri a(z) winrt::hstring-ből van felépítve.

public:
    Uri(winrt::hstring uri) const;

De a hstring rendelkezik konverziós konstruktorokkal, amelyek lehetővé teszik, hogy anélkül dolgozzon vele, hogy tisztában kellene lennie vele. Íme egy kódrészlet, amely bemutatja, hogyan hozhat létre Uri széles karakterlánc-literálból, széles karakterlánc-nézetből és std::wstring.

#include <winrt/Windows.Foundation.h>
#include <string_view>

using namespace winrt;
using namespace Windows::Foundation;

int main()
{
    using namespace std::literals;

    winrt::init_apartment();

    // You can make a Uri from a wide string literal.
    Uri contosoUri{ L"http://www.contoso.com" };

    // Or from a wide string view.
    Uri contosoSVUri{ L"http://www.contoso.com"sv };

    // Or from a std::wstring.
    std::wstring wideString{ L"http://www.adventure-works.com" };
    Uri awUri{ wideString };
}

Az Uri::Domain tulajdonságelérő hstringtípusú.

public:
    winrt::hstring Domain();

De ismét, ennek a részletnek a tudatában lenni nem szükséges, köszönhetően a hstringkonverziós operátorának a std::wstring_view-hez.

// Access a property of type hstring, via a conversion operator to a standard type.
std::wstring domainWstring{ contosoUri.Domain() }; // L"contoso.com"
domainWstring = awUri.Domain(); // L"adventure-works.com"

// Or, you can choose to keep the hstring unconverted.
hstring domainHstring{ contosoUri.Domain() }; // L"contoso.com"
domainHstring = awUri.Domain(); // L"adventure-works.com"

Hasonlóképpen, IStringable::ToString visszaadja a hstring-ot.

public:
    hstring ToString() const;

Az Uri implementálja az IStringable felületet.

// Access hstring's IStringable::ToString, via a conversion operator to a standard type.
std::wstring tostringWstring{ contosoUri.ToString() }; // L"http://www.contoso.com/"
tostringWstring = awUri.ToString(); // L"http://www.adventure-works.com/"

// Or you can choose to keep the hstring unconverted.
hstring tostringHstring{ contosoUri.ToString() }; // L"http://www.contoso.com/"
tostringHstring = awUri.ToString(); // L"http://www.adventure-works.com/"

A hstring::c_str függvény használatával szabványos szélessztringet nyerhet ki egy hstring (ugyanúgy, mint egy std::wstring).

#include <iostream>
std::wcout << tostringHstring.c_str() << std::endl;

Ha van egy hstring, akkor készíthet belőle egy Uri.

Uri awUriFromHstring{ tostringHstring };

Vegyünk egy olyan módszert, amely egy hstringvesz fel.

public:
    Uri CombineUri(winrt::hstring relativeUri) const;

Az imént látott lehetőségek az ilyen esetekben is érvényesek.

std::wstring contact{ L"contact" };
contosoUri = contosoUri.CombineUri(contact);
    
std::wcout << contosoUri.ToString().c_str() << std::endl;

hstring tagja a std::wstring_view konverziós operátor, és az átalakítás költség nélkül történik.

void legacy_print(std::wstring_view view);

void Print(winrt::hstring const& hstring)
{
    legacy_print(hstring);
}

winrt::hstring függvények és operátorok

Számos konstruktor, operátor, függvény és iterátor lett implementálva winrt::hstring.

A hstring egy tartomány, ezért használhatja tartományalapú forvagy std::for_each. Emellett összehasonlító operátorokat is biztosít a C++ Standard Könyvtárban található megfelelőkkel való természetes és hatékony összehasonlításhoz. A hstring az asszociatív tárolók kulcsaként való használatához szükséges minden elemet tartalmaz.

Felismerjük, hogy számos C++ kódtár használ std::sztringet, és kizárólag UTF-8 szöveggel dolgozik. A kényelmes használat érdekében biztosítunk olyan segédeszközöket, mint például winrt::to_string, és winrt::to_hstring, az oda-vissza konvertáláshoz.

WINRT_ASSERT egy makródefiníció, amely _ASSERTE-re bontakozik ki.

winrt::hstring w{ L"Hello, World!" };

std::string c = winrt::to_string(w);
WINRT_ASSERT(c == "Hello, World!");

w = winrt::to_hstring(c);
WINRT_ASSERT(w == L"Hello, World!");

A hstring függvényekkel és operátorokkal kapcsolatos további példákért és információkért tekintse meg a winrt::hstring API referenciatémakört.

A winrt::hstring és winrt::param::hstring indoklása

A Windows futtatókörnyezet wchar_t karakterekkel van implementálva, de a Windows futtatókörnyezet alkalmazás bináris felülete (ABI) nem része annak, amit az std::wstring vagy az std::wstring_view biztosít. Ezek használata jelentős hatékonysághiányhoz vezetne. Ehelyett a C++/WinRT a winrt::hstring-et nyújtja, amely egy a mögöttes HSTRING-nelkonzisztens nem módosítható sztringet ábrázol, hasonló felületen megvalósítva, mint a std::wstring.

Észreveheti, hogy C++/WinRT bemeneti paraméterek, amelyeknek logikusan el kellene fogadniuk winrt::hstring, valójában winrt::param::hstringformátumot várnak. A param-névtér olyan típusokat tartalmaz, amelyek kizárólag a bemeneti paraméterek optimalizálására szolgálnak a C++ standard kódtártípusokhoz való természetes kötéshez, és elkerülik a másolatokat és az egyéb hatékonysági problémákat. Ezeket a típusokat nem szabad közvetlenül használnia. Ha optimalizálást szeretne használni a saját függvényeihez, használja az std::wstring_view. Lásd még Paraméterek átadása az ABI határvonalán.

A lényeg az, hogy nagyrészt figyelmen kívül hagyhatja a Windows Runtime karakterlánc-kezelésének sajátosságait, és hatékonyan dolgozhat a már ismert módszerekkel. És ez fontos, tekintve, hogy a Windows Runtime-ban milyen nagy mértékben használják a karakterláncokat.

Sztringek formázása

A sztringformázás egyik lehetősége std::wostringstream. Az alábbi példa egy egyszerű hibakeresési nyomkövetési üzenetet formáz és jelenít meg.

#include <sstream>
#include <winrt/Windows.UI.Input.h>
#include <winrt/Windows.UI.Xaml.Input.h>
...
void MainPage::OnPointerPressed(winrt::Windows::UI::Xaml::Input::PointerRoutedEventArgs const& e)
{
    winrt::Windows::Foundation::Point const point{ e.GetCurrentPoint(nullptr).Position() };
    std::wostringstream wostringstream;
    wostringstream << L"Pointer pressed at (" << point.X << L"," << point.Y << L")" << std::endl;
    ::OutputDebugString(wostringstream.str().c_str());
}

A tulajdonság beállításának helyes módja

Egy tulajdonságot úgy állíthat be, hogy egy értéket ad át egy setter függvénynek. Íme egy példa.

// The right way to set the Text property.
myTextBlock.Text(L"Hello!");

Az alábbi kód helytelen. Lefordítja, de mindössze annyit tesz, hogy módosítja a Text() hozzáférő függvény által visszaadott ideiglenes winrt::hstring-t, majd eldobja az eredményt.

// *Not* the right way to set the Text property.
myTextBlock.Text() = L"Hello!";

Fontos API-k