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. Я не могу найти документацию о том, как правильно долго печатать карту. Любые предложения, как я должен долго печатать карту?

Спасибо,

1 ответ

Решение

Я никогда не имел дело с 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,

Вторая часть вопроса - ТИП КАРТА для 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. ТИП КАРТА дляT_LONG описывается в $PERLLIB/ExtUtils/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
Другие вопросы по тегам