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

我正在使用SWIG生成一个调用’c’共享库的PHP扩展。 除了下面的情况,我能够让大多数事情发挥作用……

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

int getAllThePortInfo(EthernetPort *ports); 

在这种情况下,参数端口实际上是EthernetPort结构的数组。 在另一个’c’程序中,我可以这样称呼它……

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

这很好用。 然后我运行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我能做些什么来让我的包装更好地理解我的意图吗?

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

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

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

 %include  %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_ethernetPortArrayethernetPortArray_getitemethernetport_number_getethernetport_mode_getdelete_ethernetPortArray都是由SWIG根据.i文件创建的。

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

干杯。

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

 %include  %include "my_lib.h" %array_functions(EthernetPort, ethernetPortArray); 

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

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