【问题标题】:Perl XS and C++ passing pointer to bufferPerl XS 和 C++ 将指针传递给缓冲区
【发布时间】:2012-07-22 04:19:23
【问题描述】:

我几乎不懂 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。

顺便说一句——我还对 T_IV 使用了类型映射“long long int”。我找不到任何关于如何正确地输入 long long 的文档。有什么建议我应该如何打字吗?

谢谢,

【问题讨论】:

    标签: perl xs


    【解决方案1】:

    我从未从 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 成功/失败返回真/假。
    • buffer 不会在失败时分配。
    • buffer 的释放器是 free

    【讨论】:

    • 您为我解决这个问题的部分答案是理解我不需要在 xsub 中使用 C++ XS 结构——Class::method(...)。我一直试图找到一个 XS 可以接受的签名,但是一旦我放弃了它,它就更容易解决了。谢谢。
    【解决方案2】:

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

    通常long 至少为 32 位,long long 至少为 64。long 的默认类型映射为 T_IV。 Perl 的long long 等价物也是T_IV

    但有时,您不想减少演员阵容的警告。因此,您可以将T_LONG 用于longT_LONG 等价于T_IV,但将返回显式转换为long 类型。 T_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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-02
      • 1970-01-01
      • 1970-01-01
      • 2014-08-15
      相关资源
      最近更新 更多