Pole a WriteOnlyArray (C++/CX)
V programu C++/CX můžete volně používat běžná pole std::array
ve stylu jazyka C++/CX (i když std::vector
je to často lepší volba), ale v libovolném rozhraní API, které je publikováno v metadatech, je nutné převést pole nebo vektor ve stylu jazyka C na Platform::Array
typ v Platform::WriteOnlyArray
závislosti na tom, jak se používá. Typ Platform::Array
není tak efektivní ani tak výkonný jako std::vector
, takže jako obecné vodítko byste se měli vyhnout jeho použití v interním kódu, který provádí velké množství operací s prvky pole.
Mezi ABI je možné předat následující typy polí:
const Platform::Array^
Platform::Array^*
Platform::WriteOnlyArray
návratová hodnota
Platform::Array^
Tyto typy polí použijete k implementaci tří druhů vzorů polí, které jsou definovány prostředí Windows Runtime.
PassArray
Používá se, když volající předá matici metodě. Typ vstupního parametru jazyka C++ je const
Platform::Array
<T.>
FillArray
Používá se, když volající předá pole pro metodu, která se má vyplnit. Typ vstupního parametru jazyka C++ je Platform::WriteOnlyArray
<T>.
ReceiveArray
Používá se, když volající obdrží pole, které metoda přidělí. V jazyce C++/CX můžete vrátit matici ve návratové hodnotě jako Array^ nebo ji můžete vrátit jako výstupní parametr jako typ Array^*.
Model PassArray
Když klientský kód předá pole do metody C++ a metoda ho nezmění, metoda přijme pole jako const Array^
. Na úrovni prostředí Windows Runtime binárního rozhraní aplikace (ABI) se označuje jako PassArray. Další příklad ukazuje, jak předat pole přidělené v JavaScriptu funkci C++, která z ní čte.
//JavaScript
function button2_click() {
var obj = new JS-Array.Class1();
var a = new Array(100);
for (i = 0; i < 100; i++) {
a[i] = i;
}
// Notice that method names are camelCased in JavaScript.
var sum = obj.passArrayForReading(a);
document.getElementById('results').innerText
= "The sum of all the numbers is " + sum;
}
Následující fragment kódu ukazuje metodu C++:
double Class1::PassArrayForReading(const Array<double>^ arr)
{
double sum = 0;
for(unsigned int i = 0 ; i < arr->Length; i++)
{
sum += arr[i];
}
return sum;
}
Model ReceiveArray
V modelu ReceiveArray kód klienta deklaruje pole a předá ho metodě, která přidělí paměť pro ni a inicializuje ji. Typ vstupního parametru jazyka C++ je ukazatel na hat: Array<T>^*
. Následující příklad ukazuje, jak deklarovat objekt pole v JavaScriptu a předat ho funkci C++, která přidělí paměť, inicializuje prvky a vrátí ho do JavaScriptu. JavaScript považuje přidělené pole za návratovou hodnotu, ale funkce jazyka C++ s ním pracuje jako s výstupním parametrem.
//JavaScript
function button3_click() {
var obj = new JS-Array.Class1();
// Remember to use camelCase for the function name.
var array2 = obj.calleeAllocatedDemo2();
for (j = 0; j < array2.length; j++) {
document.getElementById('results').innerText += array2[j] + " ";
}
}
Následující fragment kódu ukazuje dva způsoby implementace metody C++:
// Return array as out parameter...
void Class1::CalleeAllocatedDemo(Array<int>^* arr)
{
auto temp = ref new Array<int>(10);
for(unsigned int i = 0; i < temp->Length; i++)
{
temp[i] = i;
}
*arr = temp;
}
// ...or return array as return value:
Array<int>^ Class1::CalleeAllocatedDemo2()
{
auto temp = ref new Array<int>(10);
for(unsigned int i = 0; i < temp->Length; i++)
{
temp[i] = i;
}
return temp;
}
Vyplnění polí
Pokud chcete přidělit pole v volajícím a inicializovat nebo upravit volaný, použijte WriteOnlyArray
. Následující příklad ukazuje, jak implementovat funkci C++, která ji používá WriteOnlyArray
a volat z JavaScriptu.
// JavaScript
function button4_click() {
var obj = new JS-Array.Class1();
//Allocate the array.
var a = new Array(10);
//Pass the array to C++.
obj.callerAllocatedDemo(a);
var results = document.getElementById('results');
// Display the modified contents.
for (i = 0; i < 10; i++) {
document.getElementById('results').innerText += a[i] + " ";
}
}
Následující fragment kódu ukazuje, jak implementovat metodu C++:
void Class1::CallerAllocatedDemo(Platform::WriteOnlyArray<int>^ arr)
{
// You can write to the elements directly.
for(unsigned int i = 0; i < arr->Length; i++)
{
arr[i] = i;
}
}
Převody polí
Tento příklad ukazuje, jak použít Platform::Array
k vytvoření dalších druhů kolekcí:
#include <vector>
#include <collection.h>
using namespace Platform;
using namespace std;
using namespace Platform::Collections;
void ArrayConversions(const Array<int>^ arr)
{
// Construct an Array from another Array.
Platform::Array<int>^ newArr = ref new Platform::Array<int>(arr);
// Construct a Vector from an Array
auto v = ref new Platform::Collections::Vector<int>(arr);
// Construct a std::vector. Two options.
vector<int> v1(begin(arr), end(arr));
vector<int> v2(arr->begin(), arr->end());
// Initialize a vector one element at a time.
// using a range for loop. Not as efficient as using begin/end.
vector<int> v3;
for(int i : arr)
{
v3.push_back(i);
}
}
Další příklad ukazuje, jak vytvořit z pole ve stylu jazyka Platform::Array
C a vrátit ho z veřejné metody.
Array<int>^ GetNums()
{
int nums[] = {0,1,2,3,4};
//Use nums internally....
// Convert to Platform::Array and return to caller.
return ref new Array<int>(nums, 5);
}
Jagged arrays
Systém typů prostředí Windows Runtime nepodporuje koncept agregovaných polí, a proto nelze použít IVector<Platform::Array<T>>
jako návratovou hodnotu nebo parametr metody ve veřejné metodě. Pokud chcete předat agregované pole nebo posloupnost sekvencí napříč ABI, použijte IVector<IVector<T>^>
.
Použití ArrayReference k zabránění kopírování dat
V některých scénářích, kdy se data předávají přes ABI do ABI Platform::Array
, a v konečném důsledku chcete tato data zpracovat v poli stylu jazyka C kvůli efektivitě, můžete použít platformu::ArrayReference , abyste zabránili další operaci kopírování. Když předáte Platform::ArrayReference
jako argument parametru, který přebírá Platform::Array
hodnotu , ArrayReference
uloží data přímo do zadaného pole ve stylu jazyka C. Jen mějte na paměti, že ArrayReference
nemá žádný zámek na zdrojových datech, takže pokud jsou data upravena nebo odstraněna v jiném vlákně před dokončením volání, výsledky nebudou definovány.
Následující fragment kódu ukazuje, jak zkopírovat výsledky DataReader
operace do Platform::Array
(obvyklého vzoru) a jak pak nahradit ArrayReference
kopírování dat přímo do pole ve stylu jazyka C:
public ref class TestReferenceArray sealed
{
public:
// Assume dr is already initialized with a stream
void GetArray(Windows::Storage::Streams::DataReader^ dr, int numBytesRemaining)
{
// Copy into Platform::Array
auto bytes = ref new Platform::Array<unsigned char>(numBytesRemaining);
// Fill an Array.
dr->ReadBytes(bytes);
// Fill a C-style array
uint8 data[1024];
dr->ReadBytes( Platform::ArrayReference<uint8>(data, 1024) );
}
};
Vyhněte se zveřejnění pole jako vlastnosti
Obecně platí, že byste se měli vyhnout zveřejnění Platform::Array
typu jako vlastnosti v ref třídě, protože celé pole je vráceno, i když se klientský kód pokouší získat přístup pouze k jednomu prvku. Pokud potřebujete zveřejnit kontejner sekvence jako vlastnost ve veřejné třídě ref, Windows::Foundation::IVector
je lepší volbou. V privátních nebo interních rozhraních API (která nejsou publikovaná do metadat) zvažte použití standardního kontejneru jazyka C++, například std::vector
.
Viz také
Systém typů
Referenční zdroje k jazyku C++/CX
Referenční informace o oborech názvů