Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Você pode usar livremente matrizes regulares no estilo C ou std::array em um programa C++/CX (embora std::vector muitas vezes seja uma escolha melhor), mas em qualquer API publicada em metadados, você deve converter uma matriz ou vetor no estilo C em um Platform::Array ou Platform::WriteOnlyArray tipo, dependendo de como ele está sendo usado. O Platform::Array tipo não é tão eficiente nem tão poderoso quanto std::vectoro , portanto, como uma diretriz geral, você deve evitar seu uso em código interno que executa muitas operações nos elementos da matriz.
Os seguintes tipos de matriz podem ser passados através da ABI:
const Platform::Array^Platform::Array^*Platform::WriteOnlyArrayvalor de retorno de
Platform::Array^
Use esses tipos de matriz para implementar os três tipos de padrões de matriz definidos pelo Tempo de Execução do Windows.
PassArray
Usado quando o chamador passa uma matriz para um método. O tipo de parâmetro de entrada C++ é constPlatform::Array<T.>
FillArray
Usado quando o chamador passa uma matriz para o método preencher. O tipo de parâmetro de entrada C++ é Platform::WriteOnlyArray<T>.
ReceiveArray
Usado quando o chamador recebe uma matriz que o método aloca. Em C++/CX, você pode retornar a matriz no valor de retorno como uma Matriz^ ou pode retorná-la como um parâmetro de saída como tipo Matriz^*.
Padrão PassArray
Quando o código do cliente passa uma matriz para um método C++ e o método não a modifica, o método aceita a matriz como um const Array^arquivo . No nível da interface binária de aplicativo (ABI) do Tempo de Execução do Windows, isso é conhecido como PassArray. O próximo exemplo mostra como passar uma matriz alocada em JavaScript para uma função C++ que lê a partir dela.
//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 trecho a seguir mostra o método 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;
}
Padrão ReceiveArray
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. O tipo de parâmetro de entrada C++ é um ponteiro para chapéu: Array<T>^*. O exemplo a seguir mostra como declarar um objeto de matriz em JavaScript e passá-lo para uma função C++ que aloca a memória, inicializa os elementos e o retorna para JavaScript. JavaScript trata a matriz alocada como um valor de retorno, mas a função C++ a trata como um parâmetro out.
//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 trecho a seguir mostra duas maneiras de implementar o método 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;
}
Preencher matrizes
Quando desejar alocar uma matriz no chamador e inicializá-la ou modificá-la no chamado, use WriteOnlyArray. O próximo exemplo mostra como implementar uma função C++ que usa WriteOnlyArray e chamá-la de 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 trecho a seguir mostra como implementar o método 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;
}
}
Conversões de array
Este exemplo mostra como usar a Platform::Array para construir outros tipos de coleções:
#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 próximo exemplo mostra como construir um Platform::Array a partir de uma matriz de estilo C e retorná-lo de um método público.
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 irregulares
O sistema do tipo Tempo de Execução do Windows não oferece suporte ao conceito de matrizes irregulares 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. Para passar uma matriz irregular ou uma sequência de sequências pela ABI, use IVector<IVector<T>^>.
Use ArrayReference para evitar copiar dados
Em alguns cenários em que os dados estão sendo passados através da ABI para um Platform::Array, e você deseja processar esses dados em uma matriz de estilo C para eficiência, você pode usar Platform::ArrayReference para evitar a operação de cópia extra. Quando você passa um Platform::ArrayReference como um argumento para um parâmetro que usa um Platform::Array, o ArrayReference armazenará os dados diretamente em uma matriz de estilo C que você especificar. Apenas esteja ciente de que ArrayReference não há bloqueio nos dados de origem, portanto, se esses dados forem modificados ou excluídos em outro thread antes que a chamada seja concluída, os resultados serão indefinidos.
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 de estilo 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) );
}
};
Evite expor uma matriz como uma propriedade
Em geral, você deve evitar expor um Platform::Array tipo como uma propriedade em uma classe ref porque toda a matriz é retornada mesmo quando o código do cliente está apenas tentando acessar um único elemento. Quando você precisa expor um contêiner de sequência como uma propriedade em uma classe ref pública, Windows::Foundation::IVector é uma escolha melhor. Em APIs privadas ou internas (que não são publicadas em metadados), considere usar um contêiner C++ padrão, como std::vector.
Ver também
Sistema de tipo
Referência da linguagem C++/CX
Referência de namespaces