Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
Вы можете свободно использовать обычные массивы стилей C или std::array в программе C++/CX (хотя std::vector это часто лучший выбор), но в любом API, опубликованном в метаданных, необходимо преобразовать массив стилей C или Platform::Array вектор в тип Platform::WriteOnlyArray в зависимости от того, как он используется.
Platform::Array Тип не является столь эффективным или std::vectorмощным, как и общий руководящий принцип, поэтому следует избежать его использования в внутреннем коде, который выполняет множество операций с элементами массива.
Следующие типы массивов могут передаваться через ABI:
const Platform::Array^Platform::Array^*Platform::WriteOnlyArrayвозвращаемое значение
Platform::Array^
Эти типы массивов используются для реализации трех типов шаблонов массивов, определенных среда выполнения Windows.
PassArray
Используется, когда вызывающий объект передает массив методу. Тип входного параметра C++ — constPlatform::Array<T>.
FillArray
Используется, когда вызывающий объект передает массив методу для заполнения. Тип входного параметра C++ — Platform::WriteOnlyArray<T>.
ReceiveArray
Используется, когда вызывающий объект получает массив, выделяемый методом. В C++/CX массив можно вернуть в возвращаемом значении в виде Array^ или в качестве выходного параметра типа Array^*.
Шаблон PassArray
Когда клиентский код передает массив методу C++ и метод не изменяет его, метод принимает массив в виде const Array^. На уровне двоичного интерфейса приложения среда выполнения Windows (ABI) это называется PassArray. В следующем примере показано, как передать массив, выделенный в JavaScript функции C++, которая считывает из него.
//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;
}
В следующем фрагменте кода показан метод 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;
}
Шаблон ReceiveArray
В шаблоне ReceiveArray клиентский код объявляет массив и передает его методу, который выделяет память для него и инициализирует его. Тип входного параметра C++ — это указатель на шляпу: Array<T>^* В следующем примере показано, как объявить объект массива в JavaScript и передать его функции C++, которая выделяет память, инициализирует элементы и возвращает массив в JavaScript. JavaScript обрабатывает выделенный массив в качестве возвращаемого значения, но функция C++ обрабатывает его как выходной параметр.
//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] + " ";
}
}
В следующем фрагменте кода показаны два способа реализации метода 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;
}
Заполнение массивов
Если необходимо выделить массив в вызывающем объекте, а затем инициализировать или изменить его в вызываемом объекте, используйте массив WriteOnlyArray. В следующем примере показано, как реализовать функцию C++, которая использует WriteOnlyArray и вызывает его из 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] + " ";
}
}
В следующем фрагменте кода показано, как реализовать метод 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;
}
}
Преобразования массивов
В этом примере показано, как использовать Platform::Array для создания других типов коллекций:
#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);
}
}
В следующем примере показано, как создать Platform::Array массив стилей C и вернуть его из общедоступного метода.
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);
}
Массивы массивов
Система типов среды выполнения Windows не поддерживает концепцию массивов массивов и, таким образом, невозможно использовать IVector<Platform::Array<T>> в качестве возвращаемого значения или параметра метода в открытом методе. Для передачи массива массивов или последовательности массивов в ABI используйте IVector<IVector<T>^>.
Используйте ArrayReference, чтобы избежать копирования данных
В некоторых сценариях, когда данные передаются через ABI в ABI Platform::Array, и в конечном счете вы хотите обработать эти данные в массиве стиле C для повышения эффективности, можно использовать Platform::ArrayReference , чтобы избежать дополнительной операции копирования. При передаче Platform::ArrayReference в качестве аргумента параметру, который принимает значение Platform::Array, ArrayReference данные будут храниться непосредственно в заданном массиве стилей C. Просто учтите, что ArrayReference не блокирует исходные данные, и если данные изменяются или удаляются в другом потоке до завершения вызова, результаты будут неопределенными.
В следующем фрагменте кода показано, как скопировать результаты DataReader операции в Platform::Array (обычный шаблон), а затем заменить ArrayReference данные непосредственно в массив стилей 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) );
}
};
Избегайте использования типа Array в качестве свойства
Как правило, следует избегать предоставления доступа к типу Platform::Array как к свойству в ссылочном классе, потому что массив возвращается целиком, даже если код клиента пытается получить доступ только к одному элементу. Если необходимо предоставить контейнер последовательности в качестве свойства в общедоступном классе ссылок, Windows::Foundation::IVector лучше выбрать. В частных или внутренних API (которые не публикуются в метаданных), рассмотрите возможность использования стандартного контейнера C++, std::vectorнапример.
См. также
Система типов
Справочник по языку C++/CX
Справочник по пространствам имен