Маршалу удалось неуправляемый массив неподписанных целых - PullRequest
2 голосов
/ 14 марта 2019

Я управлял массивом беззнаковых целых:

array<unsigned int> ^intParams

У меня есть встроенная функция, которая принимает в качестве аргумента:

const unsigned int *intParams

Я пытался использовать Marshal :: Copy следующим образом:

IntPtr ptr_intParams = Marshal::AllocHGlobal( intParams->Length * sizeof( unsigned int ) );
Marshal::Copy( intParams, 0, ptr_intParams, intParams->Length );

но похоже, что Marshal :: Copy не поддерживает неподписанные типы (?)

Как правильно преобразовать этот управляемый массив в неуправляемый?

Ответы [ 2 ]

1 голос
/ 20 марта 2019

Преобразование массива является распространенной проблемой в C ++ / CLI и, следовательно, имеет элегантное решение: pin_ptr<>. Используйте это так:

array<unsigned int> ^intParams;
// code that assigns a managed array to intParams
pin_ptr<unsigned int> intParamsPtr = &intParams [0];
// code that uses intParamsPtr as unsigned int*

Обратите внимание, что этот код не включает в себя копирование элементов. Он просто помещает указатель на начало управляемого массива и «закрепляет» его, поэтому его нельзя перемещать в памяти во время сбора мусора. К счастью, расположение целочисленных массивов - со знаком, без знака и с любым размером элемента - одинаково на управляемой и неуправляемой стороне, поэтому преобразование элементов не требуется.

Прикрепленный указатель действителен только в блоке, в котором он определен. Как только он выходит из области видимости (например, после закрывающей фигурной скобки), указатель автоматически становится недействительным. Нет необходимости избавляться от указателя.

0 голосов
/ 15 марта 2019

Хорошо, это было просто ... Мне удалось сделать это так:

std::vector<unsigned int> vec_intParams( intParams->Length );
for ( size_t i = 0; i < vec_intParams.size( ); ++i )
    vec_intParams[i] = intParams[i];

... и позже в коде, когда я хочу использовать указатель, я просто делаю это:

vec_intParams.data( )
...