Aracılığıyla paylaş


Dizi ve WriteOnlyArray (C++/CX)

Normal C stili dizileri veya std::array bir C++/CX programında (genellikle daha iyi bir seçenek olsa std::vector da) serbestçe kullanabilirsiniz, ancak meta verilerde yayımlanan herhangi bir API'de, nasıl kullanıldığına bağlı olarak C stili bir diziyi veya vektörün bir Platform::Array veya Platform::WriteOnlyArray türüne dönüştürmeniz gerekir. Türü Platform::Array ne kadar verimli ne de kadar std::vectorgüçlüdür, bu nedenle genel bir yönerge olarak dizi öğelerinde çok sayıda işlem gerçekleştiren iç kodda kullanılmasını önlemeniz gerekir.

Aşağıdaki dizi türleri ABI boyunca geçirilebilir:

  1. const Platform::Array^

  2. Platform::Array^*

  3. Platform::WriteOnlyArray

  4. dönüş değeri Platform::Array^

bu dizi türlerini, Windows Çalışma Zamanı tarafından tanımlanan üç dizi deseni türünü uygulamak için kullanırsınız.

PassArray
Çağıran bir diziyi bir yönteme geçirdiğinde kullanılır. C++ giriş parametre türü T'dirconst<Platform::Array>.

FillArray
Çağıran, yönteminin doldurulması için bir dizi geçirdiğinde kullanılır. C++ giriş parametre türü T'dirPlatform::WriteOnlyArray<>.

ReceiveArray
Çağıran, yönteminin ayırdığını bir dizi aldığında kullanılır. C++/CX'te dönüş değerindeki diziyi Array^ olarak döndürebilir veya Dizi^* türünde bir out parametresi olarak döndürebilirsiniz.

PassArray deseni

İstemci kodu bir diziyi bir C++ yöntemine geçirirse ve yöntemi bunu değiştirmezse, yöntemi diziyi olarak const Array^kabul eder. Windows Çalışma Zamanı uygulama ikili arabirimi (ABI) düzeyinde bu, PassArray olarak bilinir. Sonraki örnekte, JavaScript'te ayrılmış bir diziyi ondan okuyan bir C++ işlevine geçirme gösterilmektedir.

//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;
}

Aşağıdaki kod parçacığı C++ yöntemini gösterir:

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 deseni

ReceiveArray deseninde, istemci kodu bir dizi bildirir ve bu dizi için belleği ayıran ve başlatan bir yönteme geçirir. C++ giriş parametresi türü bir işaretçiden şapkayadır: Array<T>^*. Aşağıdaki örnekte JavaScript'te bir dizi nesnesinin nasıl bildirilip belleği ayıran, öğeleri başlatan ve JavaScript'e döndüren bir C++ işlevine nasıl geçirildiğini gösterilmektedir. JavaScript, ayrılan diziyi bir dönüş değeri olarak değerlendirir, ancak C++ işlevi bunu bir out parametresi olarak değerlendirir.

//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] + " ";
    }
}

Aşağıdaki kod parçacığı C++ yöntemini uygulamanın iki yolunu gösterir:


// 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;
}

Dizileri doldurma

Çağıranda bir dizi ayırmak ve çağıran içinde diziyi başlatmak veya değiştirmek istediğinizde kullanın WriteOnlyArray. Sonraki örnekte, JavaScript kullanan ve javascript'ten çağıran bir C++ işlevinin WriteOnlyArray nasıl uygulandığını gösterir.

// 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] + " ";
    }
}

Aşağıdaki kod parçacığında C++ yönteminin nasıl uygulandığı gösterilmektedir:

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;
    }   
}

Dizi dönüştürmeleri

Bu örnekte, diğer koleksiyon türlerini oluşturmak için nasıl Platform::Array kullanılacağı gösterilmektedir:

#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);
    }   
}

Sonraki örnekte C stili bir diziden oluşturma Platform::Array ve bunu genel bir yöntemden döndürme gösterilmektedir.

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);
}

Pürüzlü diziler

Windows Çalışma Zamanı türündeki sistem, pürüzlü dizi kavramını desteklemez ve bu nedenle ortak bir yöntemde dönüş değeri veya yöntem parametresi olarak kullanamazsınızIVector<Platform::Array<T>>. ABI'de pürüzlü bir diziyi veya dizi dizisini geçirmek için kullanın IVector<IVector<T>^>.

Veri kopyalamayı önlemek için ArrayReference kullanma

Verilerin ABI üzerinden bir Platform::Arrayiçine geçirildiği ve nihai olarak verimlilik için bu verileri C stili bir dizide işlemek istediğiniz bazı senaryolarda, ek kopyalama işleminden kaçınmak için Platform::ArrayReference kullanabilirsiniz. bir parametresini alan Platform::ArrayArrayReference bir parametreye bağımsız değişken olarak geçirdiğinizdePlatform::ArrayReference, verileri doğrudan belirttiğiniz C stili bir dizide depolar. Kaynak verilerde kilidi olmadığını unutmayın ArrayReference , bu nedenle arama tamamlanmadan önce başka bir iş parçacığında veriler değiştirilir veya silinirse sonuçlar tanımsız olur.

Aşağıdaki kod parçacığında, bir DataReader işlemin sonuçlarının bir (normal düzen) içine Platform::Array nasıl kopyalanması ve ardından verilerin doğrudan C stili bir diziye kopyalanması için yerine nasıl ArrayReference geçiş yapılacağını gösterilmektedir:

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) );
    }
};

Diziyi özellik olarak ortaya çıkarmaktan kaçının

Genel olarak, istemci kodu yalnızca tek bir Platform::Array öğeye erişmeye çalışırken bile dizinin tamamı döndürülür çünkü bir türü bir başvuru sınıfında özellik olarak göstermekten kaçınmanız gerekir. Bir dizi kapsayıcısını genel başvuru sınıfında özellik olarak kullanıma sunmanız gerektiğinde, Windows::Foundation::IVector daha iyi bir seçimdir. Özel veya iç API'lerde (meta verilerde yayımlanmaz), gibi std::vectorstandart bir C++ kapsayıcısı kullanmayı göz önünde bulundurun.

Ayrıca bkz.

Tür Sistemi
C++/CX Dil Başvurusu
Ad Alanları Başvurusu