Array と WriteOnlyArray (C++/CX)Array and WriteOnlyArray (C++/CX)

通常の C スタイル配列または std::array C++/cx プログラムで自由に使用できますが ( std::vector 多くの場合、より適しています)、メタデータに公開されている API では、C スタイルの配列またはベクターを、 Platform::Array Platform::WriteOnlyArray 使用方法に応じてまたは型に変換する必要があります。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. Platform::Array型は効率的でも強力でもありません std::vector 。そのため、一般的なガイドラインとして、配列要素で多くの操作を実行する内部コードでの使用を避ける必要があります。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.

次の配列型は、ABI を介して渡すことができます。The following array types can be passed across the ABI:

  1. const Platform::Array^

  2. Platform::Array^*

  3. Platform::WriteOnlyArray

  4. 戻り値Platform::Array^return value of Platform::Array^

これらの配列型は、Windows ランタイムによって定義される3種類の配列パターンを実装するために使用します。You use these array types to implement the three kinds of array patterns that are defined by the Windows Runtime.

PassArrayPassArray</span> 呼び出し元が、配列をメソッドに渡すときに使用します。Used when the caller passes an array to a method. C++ 入力パラメーターの型はです const Platform::Array <T> 。The C++ input parameter type is const Platform::Array<T>.

FillArrayFillArray</span> 呼び出し元が、メソッドが入力する配列を渡すときに使用します。Used when the caller passes an array for the method to fill. C++ 入力パラメーターの型はです Platform::WriteOnlyArray <T> 。The C++ input parameter type is Platform::WriteOnlyArray<T>.

ReceiveArrayReceiveArray</span> 呼び出し元が、メソッドが割り当てる配列を受け取るときに使用します。Used when the caller receives an array that the method allocates. C++/CX では、配列を Array^ として戻り値で返すことも、型 Array^* として Out パラメーターとして返すこともできます。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^*.

PassArray パターンPassArray pattern

クライアントコードが配列を C++ メソッドに渡し、メソッドがその配列を変更しない場合、メソッドは配列をとして受け入れ 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^. Windows ランタイムアプリケーションバイナリインターフェイス (ABI) レベルでは、これを " Pass array" と呼びます。At the Windows Runtime application binary interface (ABI) level, this is known as a PassArray. 次の例は、JavaScript に割り当てられた配列を、読み取り側の C++ 関数に渡す方法を示しています。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;
}

次のスニペットは、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;
}

ReceiveArray パターンReceiveArray pattern

Receivearrayパターンでは、クライアントコードは配列を宣言し、それをメモリを割り当てて初期化するメソッドに渡します。In the ReceiveArray pattern, client code declares an array and passes it to a method which allocates the memory for it and initializes it. C++ 入力パラメーターの型は、hat へのポインターです Array<T>^*The C++ input parameter type is a pointer-to-hat: Array<T>^*. 次の例は、JavaScript で配列オブジェクトを宣言し、それを、メモリを割り当て、要素を初期化して JavaScript に返す C++ 関数に渡す方法を示しています。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. JavaScript は、割り当てられた配列を戻り値として扱いますが、C++ 関数は出力パラメーターとして扱います。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] + " ";
    }
}

次のスニペットは、C++ メソッドを実装する 2 通りの方法を示します。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;
}

Fill 配列Fill arrays

配列を呼び出し元で割り当て、呼び出し先で初期化または変更する場合は、 WriteOnlyArrayを使用します。When you want to allocate an array in the caller, and initialize or modify it in the callee, use WriteOnlyArray. 次の例は、 WriteOnlyArray を使用する C++ 関数を実装して、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] + " ";
    }
}

次のスニペットは、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;
    }   
}

配列変換Array conversions

この例では、を使用して Platform::Array 他の種類のコレクションを構築する方法を示します。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);
    }   
}

次の例では、 Platform::Array C スタイル配列からを構築し、パブリックメソッドから返す方法を示します。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);
}

ジャグ配列Jagged arrays

Windows ランタイムの型システムは、ジャグ配列の概念をサポートしていないため、パブリック メソッドで IVector<Platform::Array<T>> を戻り値またはメソッド パラメーターとして使用することはできません。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. ABI を通じてジャグ配列またはシーケンスのシーケンスを渡すには、 IVector<IVector<T>^>を使用します。To pass a jagged array or a sequence of sequences across the ABI, use IVector<IVector<T>^>.

ArrayReference 使用による、データ コピーの回避Use ArrayReference to avoid copying data

データが ABI を介してに渡されていて、 Platform::Array 最終的にはそのデータを C スタイル配列で処理して効率を上げる場合は、 Platform:: arrayreferenceを使用して余分なコピー操作を回避することができます。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. Platform::ArrayReference 受け取るパラメーターに引数としてを渡すと、は Platform::Array 、指定した ArrayReference C スタイル配列にデータを直接格納します。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. ArrayReference にソース データへのロック オンがないため、呼び出しが完了する前に別のスレッドでそのデータが変更されるかまたは削除された場合、結果は不確定になることに注意してください。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.

次のコードスニペットは、操作の結果をにコピーする方法 DataReader Platform::Array (通常のパターン) と、を代わりにデータを ArrayReference C スタイル配列に直接コピーする方法を示しています。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) );
    }
};

配列をプロパティとして公開することを回避する方法Avoid exposing an Array as a property

一般に、ref クラスで Platform::Array 型をプロパティとして公開することは避ける必要があります。これは、クライアント コードが単一要素にアクセスしようとしている場合でも、配列全体が返されるためです。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. パブリック ref クラスでシーケンスコンテナーをプロパティとして公開する必要がある場合は、を使用することを Windows::Foundation::IVector お勧めします。When you need to expose a sequence container as a property in a public ref class, Windows::Foundation::IVector is a better choice. プライベートまたは内部 Api (メタデータには発行されません) では、などの標準 C++ コンテナーの使用を検討してください std::vectorIn private or internal APIs (which are not published to metadata), consider using a standard C++ container such as std::vector.

関連項目See also

型システムType System
C++/CX 言語リファレンスC++/CX Language Reference
名前空間のリファレンスNamespaces Reference