Как мне преобразовать cli :: array в собственный массив из собственного кода? - PullRequest
4 голосов
/ 13 октября 2011

Я пишу встроенную оболочку вокруг управляемого компонента, написанного на C ++ \ CLI.

У меня есть следующая функция в управляемом коде:

array<Byte>^ Class::Function();

Я хочу предоставить эту функцию из собственного класса C ++ со следующей подписью:

shared_array<unsigned char> Class::Function();

Я дошел до вызова управляемой функции из собственного кода, но я не уверен, как безопасно скопировать управляемый массив в неуправляемый.

gcroot<cli::array<System::Byte>^> managedArray = _managedObject->Function();

Ответы [ 2 ]

6 голосов
/ 14 октября 2011

Есть два обычных подхода:

  1. Выполните маршалинг с использованием собственного кода, который требует использования pin_ptr<>:

    boost::shared_array<unsigned char> convert(array<unsigned char>^ arr)
    {
        boost::shared_array<unsigned char> dest(new unsigned char[arr->Length]);
        pin_ptr<unsigned char> pinned = &arr[0];
        unsigned char* src = pinned;
        std::copy(src, src + arr->Length, dest.get());
        return dest;
    }
    
  2. Выполните маршалинг с помощью управляемого кода, который требует использования Marshal класса:

    boost::shared_array<unsigned char> convert(array<unsigned char>^ arr)
    {
        using System::Runtime::InteropServices::Marshal;
    
        boost::shared_array<unsigned char> dest(new unsigned char[arr->Length]);
        Marshal::Copy(arr, 0, IntPtr(dest.get()), arr->Length);
        return dest;
    }
    

Как правило, я бы предпочел последний подход, так как первый может снизить эффективность GC, если массив большой.

0 голосов
/ 14 октября 2011

Взгляните на pin_ptr, он позволяет передавать адрес управляемого класса в неуправляемую функцию.

...