swig-php包装器使用指针,c代码是一个数组

时间:2010-12-21 22:55:09

标签: php c arrays pointers swig

我正在使用SWIG生成一个调用'c'共享库的PHP扩展。除了以下情况外,我能够让大部分工作得以实现......

在我的'c'代码中我声明了一个函数(请注意结构和函数名称已被更改以保护无辜者):

int getAllThePortInfo(EthernetPort *ports);

在这种情况下,参数 ports 实际上是一个EthernetPort结构数组。在另一个'c'程序中,我本可以这样称呼它......

EthernetPort ports[4];
int rval = getAllThePortInfo(ports);
<etc>
<etc>

这很好用。然后我运行SWIG,生成我的共享库,并且所有构建都很好。我得到了我可以调用的PHP代码......

$ports = new_ethernetport();
$rval = getAllThePortInfo($ports);

这会导致PHP抛出以下错误: php:free():指针无效:0x099cb610

所以,我尝试做类似的事情......

$ports = array(new_ethernetport(), new_ethernetport(), new_ethernetport(), new_ethernetport());
$rval = getAllThePortInfo($ports);

然后PHP抱怨... PHP致命错误:在getAllThePortInfo的参数1中键入错误。预期SWIGTYPE_p_EthernetPort

我认为正在发生的是PHP(和SWIG)没有区分指针和数组,而在包装器中,它正在考虑“指向单个结构的指针”,实际上,它是一个结构数组。

我能用PHP做点什么吗?分配一块内存,我可以用它作为存储多个结构的空间吗?

SWIG是否可以做些什么来让我的包装更好地理解我的意图?

我真的很感激任何建议。感谢。

2 个答案:

答案 0 :(得分:1)

carrays.i确实得到了我的问题的答案......

在SWIG界面文件中,我有以下几行......

%include <carrays.i>
%array_functions(EthernetPort, ethernetPortArray);
%include "my_lib.h"

“my_lib.h”包含EthernetPort结构的typedef,以及函数声明......

#define NUM_ETHERNET_PORTS 4

typedef struct {
    int number;
    mode_t mode;
} EthernetPort;

int getAllThePortInfo(EthernetPort *ports);

运行SWIG并构建共享库 my_lib.so 后,我可以使用以下PHP代码......

$ports = new_ethernetPortArray(NUM_ETHERNET_PORTS);
$rval = getAllThePortInfo($ports);

$port0 = ethernetPortArray_getitem($ports, 0);
$pnum = ethernetport_number_get($port1);
$pmode = ethernetport_mode_get($port1);

// port1 port2 port3 etc etc 

delete_ethernetPortArray($ports);

php函数 new_ethernetPortArray ethernetPortArray_getitem ethernetport_number_get ethernetport_mode_get delete_ethernetPortArray 全部由SWIG基于.i文件创建。

SWIG启用的另一个好处是在我的PHP代码中使用#define(例如NUM_ETHERNET_PORTS),允许我为我的一些常见数据提供一个位置。我喜欢。 : - )

干杯。

答案 1 :(得分:0)

@DoranKatt,您的解决方案也适用于我,只需进行一次小调整。我不得不改变swig文件中的顺序:

%include <carrays.i>
%include "my_lib.h"
%array_functions(EthernetPort, ethernetPortArray);

使用原始顺序我发现它生成的代码没有编译,因为数组函数引用了稍后包含在&#34; my_lib.h&#34;中的类型。当然,我的代码使用了不同的名称和类型,但为了清楚起见,我保留了原作者名称。

感谢您发布原始问题和答案。这让我脱离了洞。我在swig文档中找不到任何相关内容。