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 런타임에서 정의 된 세 가지 배열 패턴을 구현 합니다.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^. ABI (Windows 런타임 응용 프로그램 이진 인터페이스) 수준에서이를 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 + + 입력 매개 변수 형식은 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++ 메서드를 구현하는 두 가지 방법을 보여 줍니다.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 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 스타일 배열에서를 생성 하 고 public 메서드에서 반환 하는 방법을 보여 줍니다.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 런타임 형식 시스템에서는 가변 배열의 개념이 지원되지 않으므로 public 메서드에서 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::ArrayArrayReference 사용자가 지정 하는 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::vector .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
C + +/CX 언어 참조C++/CX Language Reference
네임 스페이스 참조Namespaces Reference