From: SourceForge.net <no...@so...> - 2009-07-29 14:54:20
|
Bugs item #2095124, was opened at 2008-09-05 15:39 Message generated for change (Settings changed) made by olly You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=101645&aid=2095124&group_id=1645 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: php Group: None >Status: Closed >Resolution: Fixed Priority: 5 Private: No Submitted By: Barry Cohen (barrycohen) Assigned to: Olly Betts (olly) Summary: [php5] Function returning object always returns new object Initial Comment: I've been working with SWIG for Python, Perl and PHP5 and have found the following to be a problem on PHP5 only. Using SWIG 1.3.36. Wrap the following C++ for php5: == example.h == class Foo { public: Foo() { i = 303; } int get_i() { return i; } Foo &update_i(Foo &f) { f.i *= 2; return f; } private: int i; }; == example.i == %module example %{ #include "example.h" %} %include "example.h" The produced example.php then contains this update function: class Foo { -- snip -- function update_i($f) { $r=Foo_update_i($this->_cPtr,$f); return is_resource($r) ? new Foo($r) : $r; } } As far as I can tell, the whole is_resource() thing is used because the function is returning an object. The problem is that $r is always a resource, so you always get a new Foo() back. Consequently, this PHP: $b = new Foo(); print $b->get_i() . "\n"; $b = $b->update_i($b); print $b->get_i() . "\n"; produces 303 303 rather than 303 606 as you would hope. This may seem like a bit of a contrived example, but the same thing happens if you create a C++ vector of structs, e.g. == example.h == struct foo { int bar; }; == example.i == %module example %rename(is_empty) empty; %include "std_vector.i" %{ #include "example.h" %} %template(v_foo) std::vector<foo>; %include "example.h" Again, the get() function in the v_foo class in example.php contains the is_resource() thing. This leads to the following PHP error: $v = new v_Foo(); $foo = new foo(); $foo->bar = 123; $v->push($foo); print $v->size() . "\n"; print $v->get(0)->bar . "\n"; This prints: 1 0 rather than 1 123 as you would expect, because a new foo() is returned from v_foo->get(). The biggest problem for me at the moment is that I can't think of a sensible workaround without modifying the way the initial C++ works. Thanks ---------------------------------------------------------------------- >Comment By: Olly Betts (olly) Date: 2009-07-29 15:54 Message: Right, the problem is that the odd assigning of the return value causes Zend to free $b. The memory gets zeroed, hence the zero. You can either remove pointless assignment to $b of the result of calling update_i(), or tell the proxy object that it doesn't own the C++ object temporarily, like so: <? include "example.php"; $b = new Foo(); print $b->get_i() . "\n"; $b->thisown = 0; $b = $b->update_i($b); $b->thisown = 1; print $b->get_i() . "\n"; The more complex case with the vector works fine with SVN trunk without any messing about. So closing this ticket now. ---------------------------------------------------------------------- Comment By: Olly Betts (olly) Date: 2009-07-29 12:09 Message: Ah no, I was processing it without -c++, it does compile. Sadly still broken, though the output for the first example is now: 303 0 Which I find harder to understand... ---------------------------------------------------------------------- Comment By: Olly Betts (olly) Date: 2009-07-29 04:46 Message: Hmm, well SVN trunk now generates C++ code which fails to compile for this example. I think this is fallout from the merge of vmiklos's PHP directors branch, so I've asked him to take a look. ---------------------------------------------------------------------- Comment By: Olly Betts (olly) Date: 2008-10-01 13:25 Message: OK, so the issue seems to be that SWIG doesn't wrap an implicit copy ctor unless you use %copyctor or -copyctor equivalent. But the PHP backend isn't aware of this. ---------------------------------------------------------------------- Comment By: Olly Betts (olly) Date: 2008-09-18 07:09 Message: Creating the new PHP-side Foo object is OK as it's the wrapped C++ object which matters (at least while we don't support directors for PHP). Your example works if you explicitly define the copy constructor in example.h: Foo(const Foo&o) : i(o.i) {} Now I just need to figure out why... ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=101645&aid=2095124&group_id=1645 |