perl xs 模块编写 - 在同一个 xs 文件中使用另一个函数 [英] perl xs module writing - Use another function from within same xs file

查看:43
本文介绍了perl xs 模块编写 - 在同一个 xs 文件中使用另一个函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 XS 的初学者,花了一些时间在网上寻找这个答案,但没有运气.问题是 XS 更改了函数的名称,当它进行编译时,我会得到一个未定义的引用错误.例如考虑下面的 XS 代码:

I'm a beginner in XS and have spent some time looking for this answer on the web with no luck. The problem is that XS changes the name of the function and when it goes to compile, I will get an undefined reference error. For example consider the XS code below:

size_t 
matrixIndex (colIndex, rowIndex,nCols,nRows)
      size_t colIndex
      size_t rowIndex
      size_t nCols
      size_t nRows
    CODE:
    size_t register i;
    RETVAL = (rowIndex * nCols) + colIndex;
    OUTPUT:
        RETVAL

然后我尝试在下面的函数中使用它

I then try to use this in the following function like this

int
matrixCopyColumnVector_dbl (colIndex,fromMatrix,nColsMatrix,nRowsMatrix,intoVector,nRowsVector)
      size_t colIndex
      SV * fromMatrix
      size_t nColsMatrix
      size_t nRowsMatrix
      SV * intoVector
      size_t nRowsVector
    CODE:
      size_t register x, n;
      if( nRowsVector != nRowsMatrix) { RETVAL = 0; return RETVAL; }
      n = 0;
      for(x=0; x<= nRowsMatrix; x++) {
         intoVector[n] = fromMatrix[matrixIndex /*USE OF FUNCTION HERE!!*/(colIndex,x,nColsMatrix,nRowsMatrix)];
         n++;
      }
      RETVAL = 1;
      return RETVAL;
    OUTPUT:
       RETVAL

然后我运行 make 并完成编译过程,并且在 undefined reference to 'matrixIndex' 的链接阶段出现错误.

I then run make and it goes through the compile process and I get an error at what appears to be the linking stage of undefined reference to 'matrixIndex'.

所以我想知道从同一个 XS 文件中调用函数的标准 XS 方式是什么?

So I am wondering what is the standard XS way to call a function from within the same XS file?

推荐答案

XS 代码创建 Perl 子程序.因此,调用 XS 函数与调用任何其他 Perl 子函数相同.

XS code creates Perl subs. So calling an XS function is the same as calling any other Perl sub.

与其处理这种复杂性和低效率,不如创建一个 C 函数而不是 Perl 子函数.(如果需要,您可以使用 XS 独立公开该 C 函数.)

Instead of dealing with that complexity and inefficiency, create a C function instead of a Perl sub. (You can independently expose that C function using XS if you want to.)

#define PERL_NO_GET_CONTEXT
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"

static UV matrixIndex(UV colIndex, UV rowIndex, UV nCols, UV nRows) {
    return (rowIndex * nCols) + colIndex;
}

MODULE = Foo::Bar  PACKAGE = Foo::Bar

int
matrixCopyColumnVector_dbl(colIndex, fromMatrix, nColsMatrix, nRowsMatrix, intoVector, nRowsVector)
    UV colIndex
    SV * fromMatrix
    UV nColsMatrix
    UV nRowsMatrix
    SV * intoVector
    UV nRowsVector
PREINIT:
    UV register x, n;
CODE:
    if (nRowsVector == nRowsMatrix) {
        RETVAL = 0;
    } else {
        n = 0;
        for (x=0; x<=nRowsMatrix; x++) {
            intoVector[n] = fromMatrix[matrixIndex(colIndex, x, nColsMatrix, nRowsMatrix)];
            n++;
        }
        RETVAL = 1;
    }
OUTPUT:
    RETVAL

您对return 的使用不正确.如果您想提前返回,请使用 XSRETURN* 宏之一.

Your use of return is incorrect. If you want to return prematurely, use one of the XSRETURN* macros.

fromMatrix[...]intoVector[...] 是完全错误的.fromMatrixintoVector 是 C 数组.(它们甚至不是 Perl 数组,这无关紧要.)

fromMatrix[...] and intoVector[...] are completely wrong. fromMatrix and intoVector are C arrays. (They aren't even Perl arrays, not that that's relevant.)

Perl 整数的大小为 IV(或 UV 表示无符号),不一定是 size_t.使用它们以获得最佳兼容性.

Perl integers are of size IV (or UV for unsigned), not necessarily size_t. Use those for best compatibility.

如果你想要可移植性,你不能假设 C99,所以你不能混合声明和代码.您需要在 PREINIT 中放置声明(或在 CODE 中使用卷曲为变量声明创建新的作用域).

If you want portability, you can't assume C99, so you can't mix declarations and code. You need to put declarations in PREINIT (or use curlies in CODE to create a new scope for variable declarations).

这篇关于perl xs 模块编写 - 在同一个 xs 文件中使用另一个函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆