- explicitcall feature removed.

- Instead of using the swig_up flag in each director method (Python, Ruby, Ocaml) to indicate
whether the explicit C++ call to the appropriate base class method or a normal
polymorphic C++ call should be made, the new approach makes one of these calls
directly from the wrapper method.
- Java/C# recursive director method calls fixed (no need for explicitcall feature to solve this now)


git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@9275 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
William S Fulton 2006-09-13 20:55:24 +00:00
commit f0d1d772fa
12 changed files with 355 additions and 303 deletions

View file

@ -83,7 +83,6 @@
<li><a href="#java_directors_classes">Director classes</a>
<li><a href="#java_directors_overhead">Overhead and code bloat</a>
<li><a href="#java_directors_example">Simple directors example</a>
<li><a href="#java_directors_explicitcall">Director base method calls</a>
</ul>
<li><a href="#common_customization">Common customization features</a>
<ul>
@ -3204,62 +3203,6 @@ directorDerived::upcall_method() invoked.
</pre>
</div>
<H3><a name="java_directors_explicitcall"></a>20.5.5 Director base method calls</H3>
<p>
There is a limitation with Java directors when calling a base class method from an overridden method.
A <tt>java.lang.StackOverflowError</tt> exception will be thrown as the code makes recursive calls from the C++ layer
to the Java layer and back again in the same method. The <a href="SWIGPlus.html#SWIGPlus_explicitcall">explicitcall feature flag</a>
is one way to work around this problem. Consider the following C++ code:
</p>
<div class="code">
<pre>
%feature("director");
%feature("explicitcall");
%include &lt;std_string.i&gt;
%inline %{
struct Thing {
virtual std::string getit() { return "Thing"; }
virtual ~Thing() {}
};
%}
</pre>
</div>
<p>
and the following Java class:
</p>
<div class="code">
<pre>
class JavaThing extends Thing {
public String getit() {
return "Java" + super.getit();
}
}
</pre>
</div>
<p>
The overridden <tt>JavaThing.getit()</tt> method will throw the <tt>java.lang.StackOverflowError</tt> exception when called.
Fixing this would impose a performance penalty on all director methods and would not be able to automatically deal with pure
virtual methods for which a method body is not always defined. Instead, users are advised to use the explicitcall
feature flag which generates an additional method <tt>getitThing()</tt>. The modified version will then avoid the recursive calls:
</p>
<div class="code">
<pre>
class JavaThing extends Thing {
public String getit() {
return "Java" + super.getitThing();
}
}
</pre>
</div>
<H2><a name="common_customization"></a>20.6 Common customization features</H2>

View file

@ -1668,86 +1668,6 @@ functions for virtual members that are already defined in a base
class.
</p>
<H3><a name="SWIGPlus_explicitcall"></a>6.13.1 Explicit base class method calls</H3>
<p>
SWIG uses standard C++ polymorphic behaviour to ensure the correct virtual method is called
when generating wrappers for virtual methods.
However, in C++ it is possible, albeit rare, to call a particular base class method in the inheritance
hierarchy. This C++ functionality is available to target languages with the
<tt>explicitcall</tt> <a href="Customization.html#Customization_feature_flags">feature flag</a> directive.
This feature only works on virtual methods and when it is specified it generates an
additional wrapper method. By default, the name of this method is the original method name mangled with
the name of the class as a suffix. However, the name of the method can be controlled by specifying a different
suffix in the <tt>suffix</tt>
<a href="Customization.html#Customization_feature_attributes">feature attribute</a>.
For example, consider the following code:
</p>
<div class="code">
<pre>
%explicitcall; // enable explicitcall feature for all virtual methods
%feature("explicitcall", suffix="Bambino") Child::describe;
struct Person {
Person() {}
virtual const char * describe() { return "Person"; }
virtual ~Person() {}
};
struct Child : Person {
virtual const char * describe() { return "Child"; }
};
</pre>
</div>
<p>
From Python, it is then possible to call explicit methods in the inheritance hierarchy.
Note the suffix names:
</p>
<div class="targetlang">
<pre>
$ python
&gt;&gt;&gt; from example import *
&gt;&gt;&gt; child = Child()
&gt;&gt;&gt; print child.describe() # normal polymorphic call
Child
&gt;&gt;&gt; print child.describePerson() # explicit Person::describe call
Person
&gt;&gt;&gt; print child.describeBambino() # explicit Child::describe call
Child
</pre>
</div>
<p>
The pseudo C++ code generated for the <tt>Person::describe</tt> methods is as follows:
</p>
<div class="code">
<pre>
// Normal virtual method wrapper
const char * Person_talk(Person *obj) {
const char * ret = obj-&gt;describe();
return ret;
}
// Additional wrapper due to %explicitcall
const char * Person_talkPerson(Person *obj) {
const char * ret = obj-&gt;Person::describe();
return ret;
}
</pre>
</div>
<p>
Please note that if this feature is enabled globally, it will apply to all virtual methods.
This includes pure virtual methods which may or may not have a body defined.
If, as is often the case, your pure virtual methods do not have a body defined you might get unresolved linker errors on some platforms.
<tt>%noexplicitcall</tt> can then be used to turn this feature off for the problem methods.
</p>
<H2><a name="SWIGPlus_nn21"></a>6.14 A brief discussion of multiple inheritance, pointers, and type checking</H2>