我正在使用 XS 在 Windows 上的 Cygwin 下使用 g++ 从我的 Perl 项目中调用第三方 DLL。其中一个 DLL 函数将结构作为参数,并以指向结构的指针的形式返回其主要结果。现在我传入一个包含 28 个整数的平面列表并填充第一个结构。然后我调用该函数。然后我想将生成的结构展平为最多 54 个整数的列表。
(这看起来像很多整数,但DLL函数相当复杂,需要很长时间才能运行,所以我认为值得。除非有人有更好的主意?)
这是接近工作。我可以说结果大多是明智的。但是有两个奇怪的问题。
当我打印出相同的变量时,我会得到不同的结果,具体取决于它是否在“for”循环中!我在下面展示这个。我已经盯着这个很久了。
一旦我到达第一个 XPUSH,我就会得到“内存不足”。
这是XS代码。
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
#include "dll.h"
MODULE = Bridge::Solver::DDS_IF PACKAGE = Bridge::Solver::DDS_IF
PROTOTYPES: ENABLE
void
SolveBoard(inlist)
SV * inlist
INIT:
struct deal dl;
struct futureTricks fut;
int target, solutions, mode, thrId;
int i, j, ret;
if ((! SvROK(inlist)) ||
(SvTYPE(SvRV(inlist)) != SVt_PVAV) ||
av_len((AV *) SvRV(inlist)) != 27)
{
XSRETURN_UNDEF;
}
printf("New INIT OK\n");
PPCODE:
dl.trump = SvIV(*av_fetch((AV *)SvRV(inlist), 0, 0));
dl.first = SvIV(*av_fetch((AV *)SvRV(inlist), 1, 0));
dl.currentTrickSuit[0] = SvIV(*av_fetch((AV *)SvRV(inlist), 2, 0));
dl.currentTrickSuit[1] = SvIV(*av_fetch((AV *)SvRV(inlist), 3, 0));
dl.currentTrickSuit[2] = SvIV(*av_fetch((AV *)SvRV(inlist), 4, 0));
dl.currentTrickRank[0] = SvIV(*av_fetch((AV *)SvRV(inlist), 5, 0));
dl.currentTrickRank[1] = SvIV(*av_fetch((AV *)SvRV(inlist), 6, 0));
dl.currentTrickRank[2] = SvIV(*av_fetch((AV *)SvRV(inlist), 7, 0));
dl.remainCards[0][0] = SvUV(*av_fetch((AV *)SvRV(inlist), 8, 0));
dl.remainCards[0][1] = SvUV(*av_fetch((AV *)SvRV(inlist), 9, 0));
dl.remainCards[0][2] = SvUV(*av_fetch((AV *)SvRV(inlist), 10, 0));
dl.remainCards[0][3] = SvUV(*av_fetch((AV *)SvRV(inlist), 11, 0));
dl.remainCards[1][0] = SvUV(*av_fetch((AV *)SvRV(inlist), 12, 0));
dl.remainCards[1][1] = SvUV(*av_fetch((AV *)SvRV(inlist), 13, 0));
dl.remainCards[1][2] = SvUV(*av_fetch((AV *)SvRV(inlist), 14, 0));
dl.remainCards[1][3] = SvUV(*av_fetch((AV *)SvRV(inlist), 15, 0));
dl.remainCards[2][0] = SvUV(*av_fetch((AV *)SvRV(inlist), 16, 0));
dl.remainCards[2][1] = SvUV(*av_fetch((AV *)SvRV(inlist), 17, 0));
dl.remainCards[2][2] = SvUV(*av_fetch((AV *)SvRV(inlist), 18, 0));
dl.remainCards[2][3] = SvUV(*av_fetch((AV *)SvRV(inlist), 19, 0));
dl.remainCards[3][0] = SvUV(*av_fetch((AV *)SvRV(inlist), 20, 0));
dl.remainCards[3][1] = SvUV(*av_fetch((AV *)SvRV(inlist), 21, 0));
dl.remainCards[3][2] = SvUV(*av_fetch((AV *)SvRV(inlist), 22, 0));
dl.remainCards[3][3] = SvUV(*av_fetch((AV *)SvRV(inlist), 23, 0));
target = SvIV(*av_fetch((AV *)SvRV(inlist), 24, 0));
solutions = SvIV(*av_fetch((AV *)SvRV(inlist), 25, 0));
mode = SvIV(*av_fetch((AV *)SvRV(inlist), 26, 0));
thrId = SvIV(*av_fetch((AV *)SvRV(inlist), 27, 0));
ret = SolveBoard(dl, target, solutions, mode, &fut, thrId);
printf("Return code %d\n", ret);
printf("Nodes %d\n", fut.nodes);
printf("Cards %d\n", fut.cards);
printf("%6s %12s %12s %12s %12s\n",
"", "suit", "rank", "equals", "score");
printf("%6d %12d %12d %12d %12d\n\n",
0, fut.suit[0], fut.rank[0], fut.equals[0], fut.score[0]);
for (i = 0; i < 13; i++)
{
printf("%6d %12d %12d %12d %12d\n",
i, fut.suit[i], fut.rank[i], fut.equals[i], fut.score[i]);
}
printf("\n%6d %12d %12d %12d %12d\n\n",
0, fut.suit[0], fut.rank[0], fut.equals[0], fut.score[0]);
printf("Trying to push nodes\n");
XPUSHs(sv_2mortal(newSViv(fut.nodes)));
printf("Trying to push cards\n");
XPUSHs(sv_2mortal(newSViv(fut.cards)));
printf("Trying to loop\n");
for (i = 0; i <= 12; i++)
{
XPUSHs(sv_2mortal(newSViv(fut.suit [i])));
XPUSHs(sv_2mortal(newSViv(fut.rank [i])));
XPUSHs(sv_2mortal(newSViv(fut.equals[i])));
XPUSHs(sv_2mortal(newSViv(fut.score [i])));
}
printf("Done looping\n");
这是DLL头文件的相关部分。
struct futureTricks
{
int nodes;
int cards;
int suit[13];
int rank[13];
int equals[13];
int score[13];
};
struct deal
{
int trump;
int first;
int currentTrickSuit[3];
int currentTrickRank[3];
unsigned int remainCards[4][4];
};
extern "C" int SolveBoard(
struct deal dl,
int target,
int solutions,
int mode,
struct futureTricks *futp,
int threadIndex);
这是输出。返回码没问题。节点和卡不是。如果你眯着眼睛,你可能会注意到 0 和 768 也出现在输出表中,所以可能存在某种偏移。
第一个奇怪的是,主表前后的两个'0'行与主表中的'0'行不同。但是,主表中的数据与预期的一样,包括第 10-12 行中的垃圾。
第二个问题是 XPUSH 没有按预期工作。
New INIT OK
Return code 1
Nodes 0
Cards 768
suit rank equals score
0 0 2 -2147319000 -2147296756
0 2 2 0 2
1 2 6 0 2
2 2 10 768 2
3 2 13 0 2
4 3 14 0 2
5 0 6 0 1
6 0 10 512 1
7 0 13 0 1
8 3 4 0 0
9 3 11 0 0
10 1773292640 -2147056120 4 -2147319000
11 1772354411 0 -2146989552 -2146837752
12 8192 35 2665016 -2147319000
0 0 2 -2147319000 -2147296756
Trying to push nodes
Out of memory!