Array und WriteOnlyArray (C++/CX)
Sie können normale C-Formatarrays oder std::array
in einem C++/CX-Programm (obwohl std::vector
häufig eine bessere Wahl ist), aber in jeder API, die in Metadaten veröffentlicht wird, müssen Sie ein C-Formatarray oder einen Vektor in einen oder Platform::WriteOnlyArray
typ Platform::Array
konvertieren, je nachdem, wie es verwendet wird. Der Platform::Array
Typ ist weder so effizient noch so leistungsfähig wie std::vector
, daher sollten Sie die Verwendung in internem Code vermeiden, der viele Vorgänge für die Arrayelemente ausführt.
Die folgenden Arraytypen können über die ABI übergeben werden:
const Platform::Array^
Platform::Array^*
Platform::WriteOnlyArray
Rückgabewert von
Platform::Array^
Sie verwenden diese Arraytypen, um die drei Arten von Arraymustern zu implementieren, die durch die Windows-Runtime definiert werden.
PassArray
Wird verwendet, wenn vom Aufrufer ein Array an eine Methode übergeben wird. Der C++-Eingabeparametertyp ist const
Platform::Array
<T.>
FillArray
Wird verwendet, wenn vom Aufrufer ein Array übergeben wird, um die Methode zu füllen. Der C++-Eingabeparametertyp ist Platform::WriteOnlyArray
<T>.
ReceiveArray
Wird verwendet, wenn vom Aufrufer ein Array empfangen wird, das von der Methode zugeordnet wird. In C++/CX können Sie das Array im Rückgabewert als Array^ oder in Form eines out-Parameters als Array^*-Typ zurückgeben.
PassArray-Muster
Wenn Clientcode ein Array an eine C++-Methode übergibt und die Methode es nicht ändert, akzeptiert die Methode das Array als ein const Array^
. Auf der Ebene Windows-Runtime Application Binary Interface (ABI) wird dies als PassArray bezeichnet. Im nächsten Beispiel wird gezeigt, wie ein Array übergeben wird, das in JavaScript zu einer C++-Funktion zugeordnet ist, die aus dem Array liest.
//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;
}
Im folgenden Codeausschnitt wird die C++-Methode veranschaulicht:
double Class1::PassArrayForReading(const Array<double>^ arr)
{
double sum = 0;
for(unsigned int i = 0 ; i < arr->Length; i++)
{
sum += arr[i];
}
return sum;
}
ReceiveArray-Muster
Im ReceiveArray-Muster deklariert der Clientcode ein Array und übergibt es an eine Methode, die den Speicher dafür zuweist und initialisiert. Der Typ des C++-Eingabeparameters ist ein Zeiger-zu-Hut: Array<T>^*
. Im folgenden Beispiel wird gezeigt, wie ein Arrayobjekt in JavaScript deklariert und an eine C++-Funktion übergeben wird, die Speicher zuordnet, Elemente initialisiert und das Arrayobjekt an JavaScript zurückgibt. Von JavaScript wird das zugeordnete Array als Rückgabewert interpretiert, von der C++-Funktion jedoch als out-Parameter.
//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] + " ";
}
}
Der folgende Codeausschnitt zeigt zwei Möglichkeiten zur Implementierung der C++-Methode:
// 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;
}
Füllbereichsarrays
Wenn Sie ein Array im Aufrufer zuordnen und es im Aufgerufenen initialisieren oder ändern möchten, verwenden Sie WriteOnlyArray
. Im nächsten Beispiel wird gezeigt, wie eine C++-Funktion, die WriteOnlyArray
verwendet, implementiert und aus JavaScript aufgerufen wird.
// 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] + " ";
}
}
Der folgende Codeausschnitt zeigt, wie die C++-Methode implementiert wird:
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;
}
}
Arraykonvertierungen
In diesem Beispiel wird gezeigt, wie Sie andere Platform::Array
Arten von Auflistungen erstellen:
#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);
}
}
Das nächste Beispiel zeigt, wie Sie ein Platform::Array
Array im C-Stil erstellen und aus einer öffentlichen Methode zurückgeben.
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);
}
Verzweigte Arrays
Das Windows Runtime-Typsystem unterstützt nicht das Konzept von verzweigten Arrays. Deshalb können Sie ein IVector<Platform::Array<T>>
nicht als Rückgabewert oder Methodenparameter in einer öffentlichen Methode übergeben. Um ein verzweigtes Array oder eine Sequenz von Sequenzen an die ABI zu übergeben, verwenden Sie IVector<IVector<T>^>
.
Verwendung von ArrayReference, um das Kopieren von Daten zu vermeiden
In einigen Szenarien, in denen Daten über die ABI in eine Platform::Array
ABI übergeben werden, und Sie letztendlich diese Daten in einem C-Formatarray aus Effizienzgründen verarbeiten möchten, können Sie Platform::ArrayReference verwenden, um den zusätzlichen Kopiervorgang zu vermeiden. Wenn Sie ein Platform::ArrayReference
Argument als Argument an einen Parameter übergeben, der ein Platform::Array
Parameter verwendet, speichert die ArrayReference
Daten direkt in einem von Ihnen angegebenen C-Formatarray. Beachten Sie, dass ArrayReference
nicht über eine Sperre für die Quelldaten verfügt. Wenn diese Daten geändert oder in einem anderen Thread gelöscht werden, bevor der Aufruf abgeschlossen wird, sind die Ergebnisse nicht definiert.
Der folgende Codeausschnitt zeigt, wie die Ergebnisse eines DataReader
Vorgangs in ein Platform::Array
(das übliche Muster) kopiert werden, und wie Sie die Daten dann direkt ArrayReference
in ein C-Formatarray kopieren:
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) );
}
};
Vermeiden, ein Array als Eigenschaft verfügbar zu machen
Im Allgemeinen sollten Sie einen Platform::Array
-Typ möglichst nicht als Eigenschaft in einer Verweisklasse verfügbar machen, da das gesamte Array zurückgegeben wird, auch wenn der Clientcode nur versucht, auf ein einzelnes Element zuzugreifen. Wenn Sie einen Sequenzcontainer als Eigenschaft in einer öffentlichen Referenzklasse verfügbar machen müssen, Windows::Foundation::IVector
ist dies eine bessere Wahl. In privaten oder internen APIs (die nicht in Metadaten veröffentlicht werden), sollten Sie einen C++-Standardcontainer wie z std::vector
. B. verwenden.
Siehe auch
Typsystem
C++-/CX-Programmiersprachenreferenz
Referenz zu Namespaces
Feedback
https://aka.ms/ContentUserFeedback.
Bald verfügbar: Im Laufe des Jahres 2024 werden wir GitHub-Issues stufenweise als Feedbackmechanismus für Inhalte abbauen und durch ein neues Feedbacksystem ersetzen. Weitere Informationen finden Sie unterFeedback senden und anzeigen für