HC4*_*ica 6 php c++ swig templates language-binding
我正在使用SWIG为C++库编写PHP包装器,但是我在使用具有模板类型实例的结构作为数据成员时遇到了问题.
假设我有以下头文件:
template <typename>
struct myvector
{
};
struct S
{
myvector<int> v;
};
myvector<int> foo();
S bar();
Run Code Online (Sandbox Code Playgroud)
和接口文件:
%module test
%{
#include "test.hpp"
%}
%include "test.hpp"
%template(IntVec) myvector<int>;
Run Code Online (Sandbox Code Playgroud)
当我尝试使用直接返回的函数时myvector,它工作正常:
$v1 = test::foo();
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试使用返回S对象的函数,并尝试访问其类型为的数据成员时myvector:
$s = test::bar();
$v2 = $s->v;
Run Code Online (Sandbox Code Playgroud)
我在运行时收到以下错误:
PHP Fatal error: Class 'myvectorT_int_t' not found in test.php on line 145
Run Code Online (Sandbox Code Playgroud)
我可能错过了我的界面文件,但我不知道是什么.有人可以帮忙吗?
据我所知,这是一个 SWIG bug。事实上已经有人报道过了。幸运的是,通过 PHP 有一个简单、可靠的解决方法class_alias:
%module test
%{
#include "test.h"
%}
%pragma(php) code="
# This code is inserted as a workaround for template bugs with SWIG
class_alias('IntVec', 'myvectorT_int_t');
"
%include "test.h"
%template(IntVec) myvector<int>;
Run Code Online (Sandbox Code Playgroud)
这里的编译指示插入代码以在生成的 PHP 文件的开头设置别名。
(还有另一种可能的解决方法 - 而不是通过 getter/setter 函数使用公共成员变量访问按预期工作)
错误报告还提到了另一种可能的解决方法,尽管我对此并不热衷,因为它需要为模板类型使用一个相当丑陋的名称。
代码__get包括:
$c=substr(get_resource_type($r), (strpos(get_resource_type($r), '__') ? strpos(get_resource_type($r), '__') + 2 : 3));
return new $c($r);
Run Code Online (Sandbox Code Playgroud)
当你到达这里时,除了指令之外$c,设置为正确的。myvectorT_int_t%template
当我们将myvector<int> get()函数添加到S生成的代码中时,结果是:
$c=substr(get_resource_type($r), (strpos(get_resource_type($r), '__') ? strpos(get_resource_type($r), '__') + 2 : 3));
if (!class_exists($c)) {
return new IntVec($r);
}
return new $c($r);
Run Code Online (Sandbox Code Playgroud)
其中关键包括通用代码,如果没有%template 和作为特殊检查来查看它是否实际上是一个IntVec.
中还有一条评论Source/Modules/php.cxx:
// FIXME: Currently we always use call_user_func for __get, so we can
// check and wrap the result. This is needless if all the properties
// are primitive types. Also this doesn't handle all the cases which
// a method returning an object does.
Run Code Online (Sandbox Code Playgroud)
最后,由相同的 Java 接口文件生成的代码是正确的。