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