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

通常の C スタイル配列を自由に使用できますまたはstd::arrayで c++/cli/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^const Platform::Array^

  2. Platform::Array^*Platform::Array^*

  3. Platform::WriteOnlyArrayPlatform::WriteOnlyArray

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

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

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

FillArray は、呼び出し元がメソッドで設定する配列を渡すときに使用されます。FillArray 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>.

ReceiveArray は、呼び出し元が、メソッドが割り当てる配列を受け取るときに使用されます。ReceiveArray 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++ メソッドに渡し、メソッドがその配列を変更しない場合、メソッドはその配列を定数 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) レベルでこれは PassArray と呼ばれます。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++ 入力パラメーターの型は、ハットへのポインター: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 (メタデータに発行されません) では、 std::vectorなどの標準 C++ コンテナーの使用を検討してください。In private or internal APIs (which are not published to metadata), consider using a standard C++ container such as std::vector.

関連項目See Also

型システムType System
Visual C 言語リファレンスVisual C++ Language Reference
名前空間参照Namespaces Reference