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

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

然后我尝试在下面的函数中使用这个
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'的链接阶段出现错误。
所以我想知道从同一个xs文件中调用函数的标准xs方法是什么?

最佳答案

xs代码创建perl sub。因此,调用xs函数与任何其他perl子函数都是一样的。
与其处理复杂性和效率低下,不如创建一个C函数而不是一个Perl子(可以使用XS独立地公开C函数)。

#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*宏之一。
fromMatrix[...]intoVector[...]完全错误。fromMatrixintoVector是c数组。(它们甚至都不是Perl数组,与此无关。)
perl整数的大小是IV(或UV表示无符号),不一定size_t。使用这些以获得最佳兼容性。
如果您想要可移植性,就不能假设c99,所以不能混合声明和代码。您需要将声明放在PREINIT中(或者使用CODE中的卷曲为变量声明创建一个新的作用域)。

07-28 01:34
查看更多