I am writing a PHP wrapper for a C++ library using SWIG, but I am having trouble using a structure with an instance of a template type as a data member.
Suppose I have the following header file:
template <typename>
struct myvector
{
};
struct S
{
myvector<int> v;
};
myvector<int> foo();
S bar();
and interface file:
%module test
%{
#include "test.hpp"
%}
%include "test.hpp"
%template(IntVec) myvector<int>;
When I try to use a function that directly returns an myvector
, it works fine:
$v1 = test::foo();
However, when I try to use a function that returns an S
object, and try to access its data member which is of type myvector
:
$s = test::bar();
$v2 = $s->v;
I get the following error at runtime:
PHP Fatal error: Class 'myvectorT_int_t' not found in test.php on line 145
I am probably missing something from my interface file, but I don't know what. Can anyone help?
As far as I can make out this is a SWIG bug. Someone else has already reported it in fact. Fortunately there's a simple, reliable workaround via PHP's
class_alias
:The pragma here inserts the code to setup the alias at the start of the generated PHP file.
(There's another possible work around too - rather than using public member variables access via getter/setter functions works as expected)
The bug report also mentions another possible workaround although I'm not keen on that since it requires using a rather ugly name for the template type.
Justification for bug assumption
The code for
__get
includes:When you get here
$c
is set tomyvectorT_int_t
which would be correct except for the%template
directive.When we add a
myvector<int> get()
function toS
the generated code results in:which crucially includes the generic code that would be correct without the
%template
and as special check to see if it's actually anIntVec
.There's also a comment in the
Source/Modules/php.cxx
:Finally the code generated by the same interface file for Java is correct.