Matriz e WriteOnlyArray (C++/CX)Array and WriteOnlyArray (C++/CX)

Você pode usar livremente matrizes regulares do estilo C ou std::array em um programa C++/CX (embora std::vector geralmente seja uma opção melhor), mas em qualquer API que é publicada nos metadados, você deve converter uma matriz C-style ou um vetor em um Platform::Array Platform::WriteOnlyArray tipo ou dependendo de como ele está sendo usado.You can freely use regular C-style arrays or std::array in a C++/CX program (although std::vector is often a better choice), but in any API that is published in metadata, you must convert a C-style array or vector to a Platform::Array or Platform::WriteOnlyArray type depending on how it is being used. O Platform::Array tipo não é tão eficiente quanto tão potente quanto std::vector , portanto, como uma diretriz geral, você deve evitar seu uso no código interno que executa muitas operações nos elementos da matriz.The Platform::Array type is neither as efficient nor as powerful as std::vector, so as a general guideline you should avoid its use in internal code that performs lots of operations on the array elements.

Os seguintes tipos de matriz podem ser passados pela ABI:The following array types can be passed across the ABI:

  1. const Platform::Array^

  2. Platform::Array^*

  3. Platform::WriteOnlyArray

  4. valor de retorno dePlatform::Array^return value of Platform::Array^

Você usa esses tipos de matriz para implementar os três tipos de padrões de matriz que são definidos pelo Windows Runtime.You use these array types to implement the three kinds of array patterns that are defined by the Windows Runtime.

PassArrayPassArray
Usada quando o chamador passa uma matriz a um método.Used when the caller passes an array to a method. O tipo de parâmetro de entrada C++ é const Platform::Array <T> .The C++ input parameter type is const Platform::Array<T>.

FillArrayFillArray
Usada quando o chamador passa uma matriz ao método para preenchimento.Used when the caller passes an array for the method to fill. O tipo de parâmetro de entrada C++ é Platform::WriteOnlyArray <T> .The C++ input parameter type is Platform::WriteOnlyArray<T>.

ReceiveArrayReceiveArray
Usada quando o chamador recebe uma matriz que o método aloca.Used when the caller receives an array that the method allocates. No C++/CX, é possível retornar a matriz no valor de retorno como um Array^ ou retorná-la o como um parâmetro de saída como o tipo Array^*.In C++/CX you can return the array in the return value as an Array^ or you can return it as an out parameter as type Array^*.

Padrão de PassArrayPassArray pattern

Quando o código do cliente passa uma matriz para um método C++ e o método não o modifica, o método aceita a matriz como um const Array^ .When client code passes an array to a C++ method and the method does not modify it, the method accepts the array as a const Array^. No nível da ABI (interface binária de aplicativo) Windows Runtime, isso é conhecido como um PassArray.At the Windows Runtime application binary interface (ABI) level, this is known as a PassArray. O exemplo a seguir mostra como passar uma matriz alocada em JavaScript a uma função C++ que lê dela.The next example shows how to pass an array that's allocated in JavaScript to a C++ function that reads from it.

//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;
}

O snippet a seguir mostra o método do C++:The following snippet shows the C++ method:

double Class1::PassArrayForReading(const Array<double>^ arr)
{
    double sum = 0;
    for(unsigned int i = 0 ; i < arr->Length; i++)
    {
        sum += arr[i];
    }
    return sum;
}

Padrão ReceiveArrayReceiveArray pattern

No padrão ReceiveArray , o código do cliente declara uma matriz e a passa para um método que aloca a memória para ela e a inicializa.In the ReceiveArray pattern, client code declares an array and passes it to a method which allocates the memory for it and initializes it. O tipo de parâmetro de entrada C++ é um ponteiro para o-Hat: Array<T>^* .The C++ input parameter type is a pointer-to-hat: Array<T>^*. O exemplo a seguir mostra como declarar um objeto de matriz em JavaScript e passá-lo a uma função C++ que aloca a memória, inicializa os elementos e o retorna ao JavaScript.The following example shows how to declare an array object in JavaScript, and pass it to a C++ function that allocates the memory, initializes the elements, and returns it to JavaScript. O JavaScript trata a matriz alocada como um valor de retorno, mas a função C++ a trata como um parâmetro de saída.JavaScript treats the allocated array as a return value, but the C++ function treats it as an 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] + " ";
    }
}

O snippet a seguir mostra duas maneiras de implementar o método do C++:The following snippet shows two ways to implement the C++ method:


// 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;
}

Matrizes de preenchimentoFill arrays

Quando você deseja alocar uma matriz no chamador e inicializá-la ou modificá-la no chamado, use WriteOnlyArray.When you want to allocate an array in the caller, and initialize or modify it in the callee, use WriteOnlyArray. O exemplo a seguir mostra como implementar uma função C++ que usa WriteOnlyArray e a chama do JavaScript.The next example shows how to implement a C++ function that uses WriteOnlyArray and call it from JavaScript.

// 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] + " ";
    }
}

O snippet a seguir mostra como implementar o método do C++:The following snippet shows how to implement the C++ method:

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;
    }   
}

Conversões de matrizArray conversions

Este exemplo mostra como usar um Platform::Array para construir outros tipos de coleções:This example shows how to use a Platform::Array to construct other kinds of collections:

#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);
    }   
}

O exemplo a seguir mostra como construir um Platform::Array de uma matriz de estilo C e retorná-lo a partir de um método público.The next example shows how to construct a Platform::Array from a C-style array and return it from a public method.

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);
}

Matrizes denteadasJagged arrays

O sistema de tipos do Windows Runtime não oferece suporte ao conceito de matrizes denteadas e, portanto, você não pode usar IVector<Platform::Array<T>> como um valor de retorno ou parâmetro de método em um método público.The Windows Runtime type system does not support the concept of jagged arrays and therefore you cannot use IVector<Platform::Array<T>> as a return value or method parameter in a public method. Para passar uma matriz denteada ou uma sequência de sequências através da ABI, use IVector<IVector<T>^>.To pass a jagged array or a sequence of sequences across the ABI, use IVector<IVector<T>^>.

Usar ArrayReference para evitar a cópia de dadosUse ArrayReference to avoid copying data

Em alguns cenários em que os dados estão sendo passados pela ABI em um Platform::Array e, em última análise, você deseja processar esses dados em uma matriz de estilo C para eficiência, é possível usar o Platform:: ArrayReference para evitar a operação de cópia extra.In some scenarios where data is being passed across the ABI into a Platform::Array, and you ultimately want to process that data in a C-style array for efficiency, you can use Platform::ArrayReference to avoid the extra copy operation. Quando você passa um Platform::ArrayReference como um argumento para um parâmetro que usa um Platform::Array , o ArrayReference irá armazenar os dados diretamente em uma matriz de estilo C que você especificar.When you pass a Platform::ArrayReference as an argument to a parameter that takes a Platform::Array, the ArrayReference will store the data directly into a C-style array that you specify. Apenas esteja ciente de que ArrayReference não tem nenhum bloqueio nos dados de origem, portanto, se esses dados forem modificados ou excluídos em outro thread antes de a chamada ser concluída, os resultados serão indefinidos.Just be aware that ArrayReference has no lock on the source data, so if it that data is modified or deleted on another thread before the call completes, the results will be undefined.

O trecho de código a seguir mostra como copiar os resultados de uma DataReader operação em um Platform::Array (o padrão usual) e, em seguida, como substituir ArrayReference para copiar os dados diretamente em uma matriz C-Style:The following code snippet shows how to copy the results of a DataReader operation into a Platform::Array (the usual pattern), and then how to substitute ArrayReference to copy the data directly into a C-style array:

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) );
    }
};

Evitar a exposição de uma matriz como uma propriedadeAvoid exposing an Array as a property

Em geral, você deve evitar expor um tipo Platform::Array como uma propriedade em uma classe ref, pois a matriz inteira será retornada mesmo quando o código do cliente estiver apenas tentando acessar um único elemento.In general, you should avoid exposing a Platform::Array type as a property in a ref class because the entire array is returned even when client code is only attempting to access a single element. Quando você precisa expor um contêiner de sequência como uma propriedade em uma classe ref pública, Windows::Foundation::IVector é uma opção melhor.When you need to expose a sequence container as a property in a public ref class, Windows::Foundation::IVector is a better choice. Em APIs privadas ou internas (que não são publicadas em metadados), considere o uso de um contêiner C++ padrão, como std::vector .In private or internal APIs (which are not published to metadata), consider using a standard C++ container such as std::vector.

Confira tambémSee also

Sistema de tipoType System
Referência de linguagem do C++/CXC++/CX Language Reference
Referência de namespacesNamespaces Reference