Perl XS和C ++将指针传递给缓冲区

时间:2012-07-22 04:19:24

标签: perl xs

我几乎不知道C ++,所以没有帮助,而我的XS并没有好多少。我正在为C ++库创建一个XS接口,我几乎所有的方法都在工作,除了一个。

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长度的文档。任何建议我应该如何长期打字?

谢谢,

2 个答案:

答案 0 :(得分:3)

我从未使用C或XS处理过C ++。如果它是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

答案 1 :(得分:1)

问题的第二部分是long long(或long long int)的TYPEMAP。

通常long至少为32位,而long long至少为64位。long的默认类型映射为T_IVlong long的Perl等效值为T_IV

但是有时候,您不想减少演员表的警告。因此,您可以将T_LONG用于longT_LONG等效于T_IV,但显式将返回值强制转换为类型longT_LONG的TYPEMAP描述为$ PERLLIB / ExtUtils / typemap

借助这些知识,您可以为long long int编写自己的TYPEMAP:

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