【发布时间】:2010-12-21 22:55:09
【问题描述】:
我正在使用 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(): invalid pointer: 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 做些什么来让我的包装器更好地理解我的意图吗?
我真的很感激任何建议。谢谢。
【问题讨论】:
-
在你的C代码中,调用者如何知道
getAllThePortInfo()需要的数组的大小?是否固定为 4? -
如果您改为声明
int getAllThePortInfo(EthernetPort ports[]);会怎样?我知道 C 编译器无论如何都会将其更改为指针,但它可能会对 SWIG 产生影响? -
也许您可以发布 interface.i 文件的一些相关部分。
-
回答您的问题... [@caf] 是的,大小是固定的。 [@netcoder] 我尝试了这种改变。它仍然是 SWIG 中的指针。在文档中,SWIG 声明它将所有数组都视为指针以方便操作。 [@mario] 我的 .i 文件没有什么特别之处。我只包含我的 .h 文件,该文件声明了函数并在其中包含一些结构和#defines。
-
昨晚我在阅读有关 SWIG 的 carrays.i 模块的信息。任何关于使用它来解决我的问题的cmets?我还没有让它工作,但会继续努力。
标签: php c arrays pointers swig