Perl XS и C++ передают указатель на буфер

Я почти не знаю C++, так что это не помогает, и мой XS ненамного лучше. Я создаю интерфейс XS для библиотеки C++, и у меня работают почти все мои методы, кроме одного.

Метод в Perl должен выглядеть так:

$return_data = $obj->readPath( $path );

Метод определяется как этот файл .h:

int readPath(const char* path, char* &buffer, bool flag=true);

«Буфер» будет выделен, если он передан в NULL.

Есть две дополнительные версии readPath с разными сигнатурами, но они не те, которые мне нужны. (И что интересно, когда я пытаюсь скомпилировать, он говорит мне, что «кандидаты» - это два, которые мне не нужны.) Это потому, что он не понимает «char * &»?

Может ли кто-нибудь помочь с xsub, который мне нужно написать?

У меня Perl 5.14.2.

Кстати, я также использовал типографию «long long int» для T_IV. Я не могу найти никакой документации о том, как правильно набрать тип long long. Любые предложения, как я должен напечатать long long?

Спасибо,


person user1446426    schedule 22.07.2012    source источник


Ответы (2)


Я никогда не имел дело с C++ из C или XS. Если бы это был C, это было бы:

void
readPath(SV* sv_path)
   PPCODE:
      {
         char*  path   = SvPVbyte_nolen(sv_path, len);
         char*  buffer = NULL;

         if (!readPath(path, &buffer, 0))
            XSRETURN_UNDEF;

         ST(0) = sv_2mortal(newSVpv(buffer, 0));
         free(buffer);

         XSRETURN(1);
      }

Надеюсь, это работает, или вы можете настроить его для работы.


Я предположил:

  • readPath возвращает true/false для успеха/неудачи.
  • buffer не выделяется при сбое.
  • Освобождающим устройством для buffer является free.
person ikegami    schedule 22.07.2012
comment
Часть вашего ответа, которая решила это для меня, заключалась в том, что я понял, что мне не нужно использовать структуру C++ XS -- Class::method(...) -- в xsub. Я продолжал пытаться найти подпись, которую принимал бы XS, но как только я покончил с этим, решить ее стало намного проще. Спасибо. - person user1446426; 22.07.2012

Вторая часть вопроса - TYPEMAP для long long (или long long int).

Обычно long имеет размер не менее 32 бит, а long long - не менее 64. Карта типов по умолчанию для long - T_IV. Эквивалентом Perl для long long также является T_IV.

Но иногда вы не хотите уменьшать количество предупреждений для приведения. Итак, вы можете использовать T_LONG вместо long. T_LONG эквивалентен T_IV, но явно возвращает тип long. TYPEMAP для T_LONG описан в $PERLLIB/ExtUtils/typemap.

Обладая этими знаниями, вы можете написать собственный TYPEMAP для long long int:

TYPEMAP: <<TYPEMAPS
long long int T_LONGLONG

INPUT
T_LONGLONG
  $var = (long long int)SvIV($arg)

OUTPUT
T_LONGLONG
  sv_setiv($arg, (IV)$var);
TYPEMAPS
person brickpool    schedule 18.11.2019