#1200 std::vector template in PHP

closed-fixed
Olly Betts
php (58)
5
2012-05-18
2011-10-26
jcf
No

In my test.i file, I have:
%include "std_vector.i"
%template(vectorDbl) std::vector<double>;
%include "test.h"

In a test.h, I have:
#include <vector>
typedef std::vector<double> DblVector;
class test
{
...
DblVector vals1, vals2;
};

In test.php, if I have:
$count = $obj->vals1->size();

At this point I get an error saying "Class vectorT_double_t not found".

If I change test.i from
%template(vectorDbl) std::vector<double>;
to
%template(vectorT_double_t) std::vector<double>;

it works just fine. The PHP wrapping code doesn't seem to be grabbing the "vectorDbl" in the template, but using a default instead.

Discussion

  • Olly Betts
    Olly Betts
    2012-01-26

    It looks like it is picking the wrong field from the node for std::vector<double> to use there.

    I don't have time to investigate at present, but if you (or anyone else) wants to investigate, it is probably a matter of finding where in Source/Modules/php.cxx the relevant bit of the _wrap file is generated and changing which field it uses.

     
  • Alan Woodland
    Alan Woodland
    2012-05-10

    This has come up again recently: http://stackoverflow.com/a/10541980/168175

    As far as I can make out the PHP code is being generated wrong. It's:

    $c=substr(get_resource_type($r), (strpos(get_resource_type($r), '__') ? strpos(get_resource_type($r), '__') + 2 : 3));
    return new $c($r);

    but if I write a similar get function instead of having them as public members the generated code for that is:

    $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);

    Which is explicitly aware of the possibility of the type being a template type rather than just the generic type name

     
  • HighCommander4
    HighCommander4
    2012-05-16

    William S. Fulton provided the following analysis of this bug on swig-user for a similar example with vector<int>:

    >> I don't see any difference in the
    >> generated code for returning std::vector<int> from a function (foo in
    >> your test) compared to a member variable (S::v in your test). There are
    >> some differences in the generated .php file.
    >>
    >>
    >> static function foo() {
    >> $r=foo();
    >> if (is_resource($r)) {
    >> $c=substr(get_resource_type($r), (strpos(get_resource_type($r), '__')
    >> ? strpos(get_resource_type($r), '__') + 2 : 3));
    >> if (class_exists($c)) return new $c($r);
    >> return new IntVec($r);
    >> }
    >> return $r;
    >> }
    >>
    >> compared to:
    >>
    >> function __get($var) {
    >> $func = 'S_'.$var.'_get';
    >> if (function_exists($func)) {
    >> $r = call_user_func($func,$this->_cPtr);
    >> if (!is_resource($r)) return $r;
    >> $c=substr(get_resource_type($r), (strpos(get_resource_type($r), '__')
    >> ? strpos(get_resource_type($r), '__') + 2 : 3));
    >> # return new $c($r);
    >> # Next two lines are new:
    >> if (class_exists($c)) return new $c($r);
    >> return new IntVec($r);
    >> }
    >> if ($var === 'thisown') return swig_example_get_newobject($this->_cPtr);
    >> return $this->_pData[$var];
    >> }
    >>
    >> I've changed the lines shown based on what is in foo() and then your
    >> test seems to work. But the __get function is a generic one for all
    >> members, so the generated code for members is going to need a rethink.
    >> I've done enough investigation for now. A comparison with the generated
    >> code for a non-templated member needs to be done next because I think
    >> that works.

     
  • Olly Betts
    Olly Betts
    2012-05-18

    • status: open --> closed-fixed
     
  • Olly Betts
    Olly Betts
    2012-05-18

    Fixed in SVN trunk r13096.