2014-09-15 4 views
3

Я использую библиотеку LAPACK для создания R-пакета с использованием C++. Я использую unique_ptr для определения массивов, какПередача unique_ptr в библиотечные функции (функция FORTRAN)

unique_ptr<double[]> my_arr(new double[arr_length]); 

тогда я прохожу этот unique_ptr к библиотеке функции (FORTRAN функции), которая принимает указатель на двойной массив и буду обновлять этот массив внутри функции, как

F77_CALL(daxpy) (&num_feat_, &beta, tmp, &inc_one, my_arr.get(), &inc_one); 

Пройдя через сеть, я заметил, что не рекомендуется передавать unique_ptr в качестве аргумента указателя функции. Однако функции библиотеки, которые я использую, нуждаются в указателе в их аргументе. Я не могу освободить указатель перед отправкой его функции, так как библиотечная функция должна обновить указатель. Есть ли эффективный способ справиться с этим?

+4

Очевидно, что это немного неудобно, поскольку вы явно обошли все механизмы, которые делают safe_ptr безопасным; но в аналогичном вопросе [здесь] (http://stackoverflow.com/questions/9908535/unique-ptr-with-an-api-that-expects-raw-pointers) консенсус, казалось, заключался в том, что при работе с API, который ожидает, что raw указатели (Fortran, C или что-то еще), которые используют .get(), в порядке, когда подпрограммы не будут выполнять управление памятью с помощью указателя (что BLAS, конечно же, не будет). Обратите внимание, что DAXPY не будет обновлять _pointer_; он обновляет данные, на которые указывает. –

+0

@ JonathanDursi Я не думаю, что это неудобно. Я думаю, что это совершенно естественно. Вызывающий код имеет уникальное право собственности на массив, и вы * знаете *, он будет жив в течение всего времени вызова библиотеки. Я думаю, что это правильный способ вызова функций, даже если они находятся в вашем собственном коде. Это предполагает, что функция не пытается взять на себя ответственность за массив и называть delete на нем позже, и в этом случае использование unique_ptr - плохая идея. –

ответ

0

Предполагая, что библиотека не возьмет на себя ответственность за массив и попробует delete, я сам думаю, что это прекрасно.

Обычно вы предпочитаете передавать по ссылке или необработанному указателю и обычно проходят только unique_ptr, когда вы передаете право собственности, поэтому я считаю, что это правильно. Код вызова сохраняет уникальное право собственности на массив.

Вы знаете, что массив не будет удален до тех пор, пока после вызова функции, когда unique_ptr выходит за пределы области действия, что именно вы хотите.

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

См. GotW #91 для краткого изложения о том, как передать (умные) указатели.

Если библиотека сохранила указатель после вызова функции, вы должны были убедиться, что unique_ptr не выходит за пределы области до того, как библиотека закончит использовать ее, что немного сложнее.

Есть несколько библиотек, которые предполагают, что вы выделите объекты в кучу и передадите их владения через необработанный указатель (я видел его в некоторых библиотеках визуализации). Они delete объект, когда они сделаны. Обычно это считается плохой практикой в ​​C++ 11, но если вам нужно вызвать такие библиотеки, вы не должны использовать unique_ptr, так как вы не хотите, чтобы объект был сам.

+0

Почему бы вам не передать 'unique_ptr' в качестве аргумента? Для меня это похоже на 'allocatable' Фортрана, и нет никаких проблем с его передачей. Когда функции возвращаются, вы получаете текущее состояние переменной. –

+0

@VladimirF В некоторых случаях, когда вы хотите передать 'unique_ptr', наиболее распространенным является передача права собственности, о котором я упоминал. [GotW # 91] (http://herbsutter.com/2013/06/05/gotw-91-solution-smart-pointer-parameters/) дает хорошее резюме. Но в большинстве случаев (например, этот) вы не передаете право собственности, и вместо этого вы должны использовать raw-указатель или ссылку. Если вы не закроете указатель (возможно, это то, о чем вы говорите), нет никаких оснований передавать ссылку «unique_ptr» по ссылке. Лично я редко нахожу, что мне нужно переустановить 'unique_ptr' и обычно может возвращаться по значению. –

Смежные вопросы