XS代码创建Perl潜艇。所以调用 XS 函数与calling https://perldoc.perl.org/perlcall.html任何其他 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*
macros.
fromMatrix[...]
and intoVector[...]
是完全错误的。fromMatrix
and intoVector
是 C 数组。 (它们甚至不是 Perl 数组,但这并不相关。)
Perl 整数的大小IV
(or UV
对于无符号),不一定size_t
。使用它们以获得最佳兼容性。
如果你想要可移植性,你就不能假设C99,所以你不能混合声明和代码。您需要将声明放入PREINIT
(或使用花式CODE
为变量声明创建新的范围)。