Merge branch 'master' into doxygen

This commit is contained in:
Vadim Zeitlin 2018-03-19 21:54:46 +01:00
commit b7f78dd5a7
232 changed files with 5648 additions and 2419 deletions

View file

@ -154,6 +154,11 @@ matrix:
env: SWIGLANG=python PY3=3 VER=3.5
sudo: required
dist: trusty
- compiler: gcc
os: linux
env: SWIGLANG=python PY3=3 VER=3.6
sudo: required
dist: trusty
- compiler: gcc
os: linux
env: SWIGLANG=python SWIG_FEATURES=-builtin VER=2.6
@ -165,11 +170,11 @@ matrix:
sudo: required
dist: trusty
- os: linux
env: SWIGLANG=python SWIG_FEATURES=-builtin SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP11=1
env: SWIGLANG=python SWIG_FEATURES=-builtin SWIG_CC=gcc-6 SWIG_CXX=g++-6 CPP11=1
sudo: required
dist: trusty
- os: linux
env: SWIGLANG=python SWIG_FEATURES=-builtin SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP11=1 PY3=3 VER=3.5
env: SWIGLANG=python SWIG_FEATURES=-builtin SWIG_CC=gcc-6 SWIG_CXX=g++-6 CPP11=1 PY3=3 VER=3.6
sudo: required
dist: trusty
- compiler: gcc
@ -184,7 +189,12 @@ matrix:
dist: trusty
- compiler: gcc
os: linux
env: SWIGLANG=python SWIG_FEATURES=-builtin PY3=3 VER=3.5 SWIGOPTPY3=
env: SWIGLANG=python SWIG_FEATURES=-builtin PY3=3 VER=3.6
sudo: required
dist: trusty
- compiler: gcc
os: linux
env: SWIGLANG=python SWIG_FEATURES=-builtin PY3=3 VER=3.6 SWIGOPTPY3=
sudo: required
dist: trusty
- compiler: gcc
@ -279,6 +289,14 @@ matrix:
env: SWIGLANG=tcl SWIG_CC=gcc-6 SWIG_CXX=g++-6 CPP14=1
sudo: required
dist: trusty
- os: linux
env: SWIGLANG=java SWIG_CC=gcc-7 SWIG_CXX=g++-7 CPP14=1
sudo: required
dist: trusty
- os: linux
env: SWIGLANG=python SWIG_CC=gcc-7 SWIG_CXX=g++-7 CPP14=1
sudo: required
dist: trusty
- compiler: gcc
os: osx
env: SWIGLANG=
@ -349,6 +367,7 @@ install:
- if test "$TRAVIS_OS_NAME" = "osx"; then source Tools/travis-osx-install.sh; fi
- if test -n "$CPP11"; then CONFIGOPTS+=(--enable-cpp11-testing --without-maximum-compile-warnings "CXXFLAGS=-std=c++11 -Wall -Wextra" "CFLAGS=-std=c11 -Wall -Wextra") && export CSTD=c11 && export CPPSTD=c++11; fi
- if test -n "$CPP14"; then CONFIGOPTS+=(--enable-cpp11-testing --without-maximum-compile-warnings "CXXFLAGS=-std=c++14 -Wall -Wextra" "CFLAGS=-std=c11 -Wall -Wextra") && export CSTD=c11 && export CPPSTD=c++14; fi
- if test -n "$CPP17"; then CONFIGOPTS+=(--enable-cpp11-testing --without-maximum-compile-warnings "CXXFLAGS=-std=c++17 -Wall -Wextra" "CFLAGS=-std=c11 -Wall -Wextra") && export CSTD=c11 && export CPPSTD=c++17; fi
- ls -la $(which $CC)
- ls -la $(which $CXX)
- $CC --version

View file

@ -11813,7 +11813,7 @@ Version 1.3.23 (November 11, 2004)
ie, no additional pointer elements are created, and
the original 'foo' and 'A.bar' can be used as parameters.
In the case of member fucntion however, still you need
In the case of member function however, still you need
to use the special variable Class::<fnc_name>_cb_ptr, ie:
foobarm(3, a, A.barm_cb_ptr)

View file

@ -7,6 +7,208 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
Version 4.0.0 (in progress)
===========================
2018-03-09: fultonwi
[Java] #1184 Fix swigReleaseOwnership() and swigTakeOwnership() regression
for non-director classes. Restores a dynamic_cast which was previously removed.
2018-03-07: llongi
Github PR #1166 - Fix preprocessor handling of macros with commas
in a // comment.
2018-02-18: JPEWdev
Patch #1164 - Add support for a command-line options file, also sometimes
called a response file. This is useful if the command-line options exceed
the system command-line length limit. To use, put the command-line options
into a file, then provide the file name prefixed with @, for example using
a file called args.txt:
swig @args.txt
2018-02-11: wsfulton
[Javascript] #1187 Fix compilation error wrapping std::complex via
std_complex.i.
2018-01-30: smarchetto
[Scilab] add type name argument in SWIG_ptr() function to cast from pointer adress to typed pointers
2018-01-16: wsfulton
Expressions following a preprocessor directive must now be separated by whitespace
or non-numeric characters. This syntax change makes the SWIG preprocessor work like
the C preprocessor in this area.
For example, the following code used be accepted as valid syntax:
#if1
#define ABC 123
#endif
Now you get an error:
example.h:1: Error: Unknown SWIG preprocessor directive: if1 (if this is a block of
target language code, delimit it with %{ and %})
example.h:3: Error: Extraneous #endif.
The following is the correct syntax:
#if 1
#define ABC 123
#endif
The following of course also works:
#if(1)
#define ABC 123
#endif
2018-01-15: wsfulton
Fix issue #1183. Floating point exception evaluating preprocessor expressions
resulting in division by zero.
2018-01-14: wsfulton
Fix issue #1172. Seg fault parsing invalid exponents in the preprocessor.
2018-01-12: Liryna
[C#] Patch #1128. Add ToArray function to std::vector wrappers.
2018-01-12: wsfulton
[Java] Fix issue #1156. Add missing throws clause for interfaces when using the
%interface family of macros.
2018-01-05: wsfulton
Fix default arguments using expressions containing -> syntax error. Problem reported on
swig-user mailing list.
2017-12-30: wsfulton
[Python] Replace pep8 with pycodestyle for checking the Python code style when
running Python tests.
2017-12-30: davedissian
Fixed a symbol lookup issue when encountering a typedef of a symbol from the tag
namespace to the global namespace when the names are identical, such as 'typedef
struct Foo Foo;'.
2017-12-13: wsfulton
[Perl] add missing support for directorfree typemaps.
2017-12-13: wsfulton
Issue #1167 Fix directorout typemaps which were causing undefined behaviour when
returning pointers by reference.
2017-12-08: olly
[PHP] Use ZEND_MODULE_GLOBALS_ACCESSOR to access globals - this
should make the generated code work with PHP 7.2.0.
2017-12-04: wsfulton
[Python] Add missing checks for failures in calls to PyUnicode_AsUTF8String. Previously a
seg fault could occur when passing invalid UTF8 strings (low surrogates), eg passing
u"\udcff" to the C layer (Python 3).
2017-11-24: joequant
Fix #1124 and return R_NilValue for null pointers
2017-11-29: wsfulton
[Java] director exception handling improvements.
When a director method throws an exception and it is caught by DirectorException
and passed back to Java using Swig::DirectorException::throwException, the Java
stack trace now contains the original source line that threw the exception.
Deprecate Swig::DirectorException::raiseJavaException, please replace usage with
Swig::DirectorException::throwException.
2017-10-26: wsfulton
Add support for C++11 ref-qualifiers when using directors.
2017-10-26: wsfulton
Fix generated code when using directors and methods returning const ref pointers.
2017-10-26: wsfulton
[C#, D, Java, Octave, R, Scilab] Port director typemaps to these additional languages.
Issue #700.
2017-10-26: radarsat1
[Ruby Python] Patch #1029 - Correct handling of null using directors and shared_ptr.
2017-10-10: joequant
[R] pass enum expressions to R. This will generate
incorrect files when there is an arithmetic expression
in the enum, but this is better than silently generating
incorrect code
2017-10-09: olly
[PHP] Fix incorrect wrapper code generated when there's a
combination of overloading, parameters with a default value
and %newobject. Fixes https://sourceforge.net/p/swig/bugs/1350/
2017-10-09: olly
Remove GCJ support. It isn't in a good state and doesn't seem to
be used, and GCC7 dropped GCJ. Closes
https://sourceforge.net/p/swig/bugs/823/
2017-10-07: olly
Fix preprocessor handling of empty macro arguments to match that of
C/C++ compilers. Fixes https://github.com/swig/swig/pull/1111 and
https://sourceforge.net/p/swig/bugs/826/
2017-10-06: wsfulton
[Python] Issue #1108. Fix platorm inconsistency in Python default argument handling.
32 bit and 64 bit compiled versions of SWIG generated different Python files
when default arguments were outside the range of 32 bit signed integers.
The default arguments specified in Python are now only those that are in the
range of a 32 bit signed integer, otherwise the default is obtained from C/C++ code.
2017-10-02: wsfulton
[C#] Fix std::complex types passed by value.
2017-10-02: wsfulton
[Javascript, Python, Ruby] Issue #732 - Missing type information for std::complex
in std_complex.i meant that previously std::complex always had to be fully qualified
in order to be wrapped with the appropriate typemaps.
2017-10-01: joequant
allow R package names with docs
allowing mulitple get accessors in R
fix smrt-pointer and NAMESPACE support
constructors now returning smart pointers (if class
declared as such)
smart-pointer classes deriving from parent smart-pointers
2017-09-29: wsfulton
Issue #1100 - Allow an instantiated template to have the same name in the target
language as the C++ template name, for example, this is now possible:
template<typename T> struct X { ... };
%template(X) X<int>;
2017-09-23: wsfulton
Issue #1098. Fix overloading of shared_ptr with underlying pointer types, eg:
void m(std::shared_ptr<T> p);
void m(T &p);
void m(T *p);
Only the first method is wrapped and the others are ignored/shadowed.
The implementation is done via a new attribute in the 'typecheck' typemap called
'equivalent'. If specified, it must contain the equivalent pointer type for overloading
and can only be used for the special SWIG_TYPECHECK_POINTER precedence level.
The shared_ptr 'typecheck' typemaps have been modified accordingly.
Here is a simplified version:
%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="T *")
T,
T CONST &,
T CONST *,
T *CONST&,
std::shared_ptr< T >,
std::shared_ptr< T > &,
std::shared_ptr< T > *,
std::shared_ptr< T > *&
{ ... }
Overloading with any of these types will result in SWIG ignoring all but the first
overloaded method by default. Without the 'equivalent' attribute, wrapping the overloaded
methods resulted in types being shadowed (scripting languages) or code that did not
compile (statically typed languages).
2017-09-19: futatuki
[Python] #1003 Add --with-2to3=/path/to/2to3 option to configure.
2017-09-18: wsfulton
Fix type promotion wrapping constant expressions of the form:
# define EXPR_MIXED1 (0x80 + 11.1) - 1
@ -164,6 +366,27 @@ Version 4.0.0 (in progress)
cpp_class_definition.i:5: Error: 'Space1::A' resolves to 'Space1::A' and
was incorrectly instantiated in scope 'Space2' instead of within scope 'Space1'.
Previously some symbols would have been instantiated in the wrong scope and led
to lots of scope problems involving SWIG typemaps, features, renames etc.
You will need to correct the scope used in other SWIG directives which do not
support 'using declarations' and 'using directives'. For example, if you previously had:
%rename(Zap) vector<int>::clear;
using namespace std;
%template(VectorInt) vector<int>;
Prior versions of SWIG incorrectly instantiated vector<int> in the global namespace
and so the %rename matched. Now the template is instantiated in the correct namespace,
so is fully qualified as std::vector<int>. The other SWIG directives need correcting as
they do not follow 'using declarations' and 'using directives'. Change it to:
%rename(Zap) std::vector<int>::clear;
using namespace std;
%template(vin) vector<int>;
*** POTENTIAL INCOMPATIBILITY ***
2017-08-16: wsfulton
Fix scope lookup for template parameters containing unary scope operators.

View file

@ -2019,37 +2019,50 @@ public class Container : global::System.IDisposable {
// Ensure that the GC doesn't collect any Element set from C#
// as the underlying C++ class stores a shallow copy
private Element elementReference;
private global::System.Runtime.InteropServices.HandleRef getCPtrAndAddReference(Element element) {
elementReference = element;
return Element.getCPtr(element);
}
public void setElement(Element e) {
examplePINVOKE.Container_setElement(swigCPtr, getCPtrAndAddReference(e));
examplePINVOKE.Container_setElement(swigCPtr, Element.getCPtr(e));
elementReference = e;
}
}
</pre>
</div>
<p>
The following typemaps will generate the desired code.
The 'csin' typemap matches the input parameter type for the <tt>setElement</tt> method.
The 'cscode' typemap simply adds in the specified code into the C# proxy class.
The following typemaps can be used to generate this code:
</p>
<div class="code">
<pre>
%typemap(csin) Element *e "getCPtrAndAddReference($csinput)"
%typemap(cscode) Container %{
// Ensure that the GC doesn't collect any Element set from C#
// as the underlying C++ class stores a shallow copy
private Element elementReference;
private global::System.Runtime.InteropServices.HandleRef getCPtrAndAddReference(Element element) {
elementReference = element;
return Element.getCPtr(element);
}
%}
%typemap(csin,
post=" elementReference = $csinput;"
) Element *e "Element.getCPtr($csinput)"
</pre>
</div>
<p>
The 'cscode' typemap simply adds in the specified code into the C# proxy class.
The 'csin' typemap matches the input parameter type and name for the <tt>setElement</tt> method and
the 'post' typemap attribute allows adding code after the PInvoke call.
The 'post' code is generated into a finally block after the PInvoke call so the resulting code isn't quite
as mentioned earlier, <tt>setElement</tt> is actually:
</p>
<div class="code">
<pre>
public void setElement(Element e) {
try {
examplePINVOKE.Container_setElement(swigCPtr, Element.getCPtr(e));
} finally {
elementReference = e;
}
}
</pre>
</div>

View file

@ -269,6 +269,11 @@
<li><a href="SWIGPlus.html#SWIGPlus_nn35">Using declarations and inheritance</a>
<li><a href="SWIGPlus.html#SWIGPlus_nested_classes">Nested classes</a>
<li><a href="SWIGPlus.html#SWIGPlus_const">A brief rant about const-correctness</a>
<li><a href="SWIGPlus.html#SWIGPlus_target_language_callbacks">Callbacks to the target language</a>
<ul>
<li><a href="SWIGPlus.html#SWIGPlus_director_classes_introduction">Introduction to director classes</a>
<li><a href="SWIGPlus.html#SWIGPlus_directors_for_function_pointers">Using directors and target language callbacks</a>
</ul>
<li><a href="SWIGPlus.html#SWIGPlus_nn42">Where to go for more information</a>
</ul>
</div>
@ -381,6 +386,7 @@
<ul>
<li><a href="Library.html#Library_shared_ptr_basics">shared_ptr basics</a>
<li><a href="Library.html#Library_shared_ptr_inheritance">shared_ptr and inheritance</a>
<li><a href="Library.html#Library_shared_ptr_overloading">shared_ptr and method overloading</a>
<li><a href="Library.html#Library_shared_ptr_templates">shared_ptr and templates</a>
<li><a href="Library.html#Library_shared_ptr_directors">shared_ptr and directors</a>
</ul>
@ -478,7 +484,7 @@
<li><a href="Typemaps.html#Typemaps_nn35">"memberin" typemap</a>
<li><a href="Typemaps.html#Typemaps_nn36">"varin" typemap</a>
<li><a href="Typemaps.html#Typemaps_nn37">"varout" typemap</a>
<li><a href="Typemaps.html#throws_typemap">"throws" typemap</a>
<li><a href="Typemaps.html#Typemaps_throws_typemap">"throws" typemap</a>
</ul>
<li><a href="Typemaps.html#Typemaps_nn39">Some typemap examples</a>
<ul>
@ -500,6 +506,9 @@
<li><a href="Typemaps.html#Typemaps_runtime_type_checker_usage">Usage</a>
</ul>
<li><a href="Typemaps.html#Typemaps_overloading">Typemaps and overloading</a>
<ul>
<li><a href="Typemaps.html#Typemaps_typecheck_pointer">SWIG_TYPECHECK_POINTER precedence level and the typecheck typemap</a>
</ul>
<li><a href="Typemaps.html#Typemaps_nn48">More about %apply and %clear</a>
<li><a href="Typemaps.html#Typemaps_nn47">Passing data between typemaps</a>
<li><a href="Typemaps.html#Typemaps_nn52">C++ "this" pointer</a>
@ -1027,6 +1036,9 @@
<li><a href="Java.html#Java_directors_threading">Director threading issues</a>
<li><a href="Java.html#Java_directors_performance">Director performance tuning</a>
<li><a href="Java.html#Java_exceptions_from_directors">Java exceptions from directors</a>
<ul>
<li><a href="Java.html#Java_customizing_director_exceptions">Customizing director exceptions</a>
</ul>
</ul>
<li><a href="Java.html#Java_allprotected">Accessing protected members</a>
<li><a href="Java.html#Java_common_customization">Common customization features</a>

View file

@ -94,6 +94,9 @@
<li><a href="#Java_directors_threading">Director threading issues</a>
<li><a href="#Java_directors_performance">Director performance tuning</a>
<li><a href="#Java_exceptions_from_directors">Java exceptions from directors</a>
<ul>
<li><a href="#Java_customizing_director_exceptions">Customizing director exceptions</a>
</ul>
</ul>
<li><a href="#Java_allprotected">Accessing protected members</a>
<li><a href="#Java_common_customization">Common customization features</a>
@ -3746,12 +3749,10 @@ Naturally, the SWIG generated C++ code and the generated Java intermediary class
<div class="code">
<pre>
public class DirectorDerived extends DirectorBase {
public DirectorDerived() {
}
class DirectorDerived extends DirectorBase {
@Override
public void upcall_method() {
System.out.println("DirectorDerived::upcall_method() invoked.");
System.out.println("DirectorDerived.upcall_method() invoked.");
}
}
</pre>
@ -3774,7 +3775,7 @@ will result in the following being output:
<div class="code">
<pre>
DirectorDerived::upcall_method() invoked.
DirectorDerived.upcall_method() invoked.
</pre>
</div>
@ -3825,45 +3826,186 @@ The disadvantage is that invocation of director methods from C++ when Java doesn
<p>
With directors routing method calls to Java, and proxies routing them
to C++, the handling of exceptions is an important concern.
The default behavior from SWIG 3.0
onwards is to convert the thrown Java exception into a SWIG defined
<code>DirectorException</code> C++ exception.
SWIG 2.0 and earlier versions didn't provide any mechanism to handle the Java director method exceptions in C++.
The default behavior for Java exceptions thrown in a director method overridden in Java is
to store the thrown Java exception into a SWIG defined
<code>Swig::DirectorException</code> C++ class exception in the C++ layer and then throw this C++ exception.
</p>
<p>
Converting Java exceptions into C++ exceptions can be done in two different ways using
the <code>director:except</code> <a href="Customization.html#Customization_features">feature</a>.
In the simplest approach, a code block is attached to each director method to
handle the mapping of Java exceptions into C++ exceptions.
Of course, should this exception be thrown, your C++ code must catch it and handle it before returning back to Java.
The default generated code <b>does not</b> attempt to handle the C++ exception, but there is a simple way
to make this all work by catching the C++ exception and extracting the original Java exception by using <tt>%catches</tt> for <tt>Swig::DirectorException</tt>.
Consider the example shown earlier with a modification to the <tt>upcall_method</tt> Java method to throw a Java exception:
</p>
<div class="code">
<pre>
%feature("director:except") MyClass::method(int x) {
jthrowable $error = jenv-&gt;ExceptionOccurred();
if ($error) {
jenv-&gt;ExceptionClear();
if (Swig::ExceptionMatches(jenv, $error, "java/lang/IndexOutOfBoundsException"))
throw std::out_of_range(Swig::JavaExceptionMessage(jenv, $error).message());
if (Swig::ExceptionMatches(jenv, $error, "$packagepath/MyJavaException"))
throw MyCppException(Swig::JavaExceptionMessage(jenv, $error).message());
throw std::runtime_error("Unexpected exception thrown in MyClass::method");
class DirectorDerived extends DirectorBase {
@Override
public void upcall_method() {
System.out.println("DirectorDerived.upcall_method() invoked.");
throw new RuntimeException("There was a problem!");
}
}
class MyClass {
/** Throws either a std::out_of_range or MyCppException on error */
void method(int x);
}
</pre>
</div>
<p>
This approach allows a flexible mapping of Java exceptions thrown by director methods into
C++ exceptions expected by a C++ caller. There
need not be any C++ <em>exception specifications</em> on the C++ method. The
utility function <code>Swig::ExceptionMatches</code>
Now, by default, the JVM will abort when <tt>example.callup(director)</tt> is called as the C++
<tt>Swig::DirectorException</tt> (storing the Java exception) is thrown and not handled by the <tt>callup</tt> method.
Needless to say this is not very user friendly and so the recommendation is to add the following
simple <tt>%catches</tt> directive before SWIG parses the <tt>callup</tt> function:
</p>
<div class="code">
<pre>
%catches(Swig::DirectorException) callup;
</pre>
</div>
<p>
Or target all wrapped methods using:
</p>
<div class="code">
<pre>
%catches(Swig::DirectorException);
</pre>
</div>
<p>
This tells SWIG to generate a C++ catch handler using some code from the <a href="Typemaps.html#Typemaps_throws_typemap">throws typemap</a> for <tt>Swig::DirectorException</tt> that SWIG supplies by default, see <a href="SWIGPlus.html#SWIGPlus_catches">Exception handling with %catches</a>.
This typemap code is written to simply catch the C++ <tt>Swig::DirectorException</tt> class and immediately
return to Java throwing the original Java exception that it has stored.
The net result is a stack trace containing the original Java exception including the location that the exception was thown from.
</p>
<div class="shell">
<pre>
DirectorDerived.upcall_method() invoked.
Exception in thread "main" java.lang.RuntimeException: There was a problem!
at DirectorDerived.upcall_method(runme.java:4)
at exampleJNI.SwigDirector_DirectorBase_upcall_method(exampleJNI.java:20)
at exampleJNI.callup(Native Method)
at example.callup(example.java:12)
at runme.main(runme.java:21)
</pre>
</div>
<p>
More on the <tt>Swig::DirectorException</tt> class can be found in the next section which details how to customize the handling of director exceptions.
</p>
<H4><a name="Java_customizing_director_exceptions">25.5.7.1 Customizing director exceptions</a></H4>
<p>
This section is for advanced customization of director exceptions.
The recommendation for most users is to use the simple <tt>%catches</tt> directive described above as it should be sufficient for most users needs.
</p>
<p>
The conversion of Java exceptions into C++ exceptions can be customized in two different ways using
the <code>director:except</code> <a href="Customization.html#Customization_features">feature</a>.
In the first approach, a code block is attached to each director method to
handle the mapping of Java exceptions into C++ exceptions.
The code block is generated just after the call up from the C++ director method into the overloaded method in Java. Its primary function is to check if a Java exception has been thrown and then handle it in C++.
The example below converts a
<tt>java.lang.IndexOutOfBoundsException</tt> into a C++ <tt>std::out_of_range</tt> exception and converts a
user's Java <tt>MyJavaException</tt> into a C++ <tt>MyCppException</tt> exception.
If the Java exception doesn't match either of these, a fallback <tt>std::runtime_error</tt> C++ exception is thrown.
</p>
<div class="code">
<pre>
%feature("director:except") MyClass::dirmethod(int x) {
jthrowable $error = jenv-&gt;ExceptionOccurred();
if ($error) {
if (Swig::ExceptionMatches(jenv, $error, "java/lang/IndexOutOfBoundsException"))
throw std::out_of_range(Swig::JavaExceptionMessage(jenv, $error).message());
if (Swig::ExceptionMatches(jenv, $error, "$packagepath/MyJavaException"))
throw MyCppException(Swig::JavaExceptionMessage(jenv, $error).message());
throw std::runtime_error("Unexpected exception thrown in MyClass::dirmethod");
}
}
class MyClass {
public:
/** Throws either a std::out_of_range or MyCppException on error */
virtual void dirmethod(int x);
virtual ~MyClass();
};
</pre>
</div>
<p>
A few special variables are expanded within the <tt>director:except</tt> feature.
</p>
<ul>
<li> The special variable <tt>$error</tt> is expanded into a unique variable name (swigerror)
and should be used for the assignment of the jthrowable exception that occurred.</li>
<li> The special variable <tt>$packagepath</tt> is
replaced by the outer package provided for SWIG generation by the -package option. </li>
<li> The special variable <tt>$directorthrowshandlers</tt> is not shown above, but is replaced
by applicable "directorthrows" typemap contents (covered later in this section). </li>
<li> The special variable <tt>$null</tt> is not shown above, but is replaced
by a suitable default constructed object for returning from the director method (or nothing if
the director method has a void return).
</li>
</ul>
<p>
Utility functions/classes in director.swg are provided to aid the exception conversion as follows:
</p>
<div class="code">
<pre>
namespace Swig {
// Helper method to determine if a Java throwable matches a particular Java class type
// Note side effect of clearing any pending exceptions
bool ExceptionMatches(JNIEnv *jenv, jthrowable throwable, const char *classname);
// Helper class to extract the exception message from a Java throwable
class JavaExceptionMessage {
public:
JavaExceptionMessage(JNIEnv *jenv, jthrowable throwable);
// Return a C string of the exception message in the jthrowable passed in the constructor
// If no message is available, null_string is return instead
const char *message(const char *null_string =
"Could not get exception message in JavaExceptionMessage") const;
};
// C++ Exception class for handling Java exceptions thrown during a director method Java upcall
class DirectorException : public std::exception {
public:
// Construct exception from a Java throwable
DirectorException(JNIEnv *jenv, jthrowable throwable);
// More general constructor for handling as a java.lang.RuntimeException
DirectorException(const char *msg);
// Return exception message extracted from the Java throwable
const char *what() const throw();
// Reconstruct and raise/throw the Java Exception that caused the DirectorException
// Note that any error in the JNI exception handling results in a Java RuntimeException
void throwException(JNIEnv *jenv) const;
// Create and throw the DirectorException
static void raise(JNIEnv *jenv, jthrowable throwable) {
throw DirectorException(jenv, throwable);
}
};
}
</pre>
</div>
<p>
The utility function <code>Swig::ExceptionMatches</code>
and class <code>Swig::JavaExceptionMessage</code> are provided to simplify
writing code for wrappers that use the <code>director:except</code> feature. The
function <code>Swig::ExceptionMatches</code> matches the type of the
@ -3871,13 +4013,10 @@ function <code>Swig::ExceptionMatches</code> matches the type of the
name, such as <code>"java/lang/IOError"</code>. If the throwable class is the same
type, or derives from the given type, <code>Swig::ExceptionMatches</code> will return true. Care must be taken to
provide the correct fully qualified name, since for wrapped exceptions the
generated proxy class will have additional package qualification, depending on
generated proxy class will have an additional package qualification, depending on
the '-package' argument and use of the <a href="#Java_namespaces">nspace
feature</a>. The special variable <code>$error</code> is expanded by SWIG into a unique variable name and
should be used for the
assignment of the exception that occurred. The special variable <code>$packagepath</code> is
replaced by the outer package provided for SWIG generation by the -package
option. The utility class <code>Swig::JavaExceptionMessage</code> is a holder
feature</a>.
The utility class <code>Swig::JavaExceptionMessage</code> is a holder
providing access to the message from the thrown Java exception.
The <code>message()</code> method returns the exception message as a <code>const char *</code>,
which is only valid during the lifetime of the holder. Any code using this message
@ -3885,20 +4024,27 @@ needs to copy it, for example into a std::string or a newly constructed C++ exce
</p>
<p>
Using the above approach to
Using the first approach above to
write handlers for a large number of methods will require
repetitive duplication of the <code>director:except</code> feature code.
To mitigate this, an alternative approach is provided via typemaps in a
repetitive duplication of the <code>director:except</code> feature code
for each director method.
To mitigate this, a second approach is provided via typemaps in a
fashion analagous to
the <a href="Typemaps.html#throws_typemap">"throws" typemap.</a> The
"throws" typemap provides an approach to automatically map all the C++
the <a href="Typemaps.html#throws_typemap">"throws" typemap</a>.
The "throws" typemap provides a way to map all the C++
exceptions listed in a method's defined exceptions (either from
a C++ <em>exception specification</em> or a <code>%catches</code>
feature) into Java exceptions.
The "directorthrows" typemap provides the inverse mapping and should contain
code to convert a suitably matching Java exception into a C++ exception.
Only use this typemap if you wish to write custom conversions of Java exceptions into C++ exceptions
and apply them to many different methods.
The default handling which uses the <code>Swig::DirectorException</code> class should otherwise meet your needs.
</p>
<p>
The example below converts a Java <code>java.lang.IndexOutOfBoundsException</code> exception
to the typemap's type, that is <code>std::out_of_range</code>:
to the typemap's type, that is a <code>std::out_of_range</code> C++ exception:
<div class="code">
<pre>
@ -3913,7 +4059,7 @@ to the typemap's type, that is <code>std::out_of_range</code>:
<p>
The "directorthrows" typemap is then used in conjunction with the
<code>director:except</code> feature if the <code>$directorthrowshandlers</code> special variable
is used in the feature code. Consider the following, which also happens to be the default:
is used in the code block. Consider the following, which also happens to be the default:
</p>
<div class="code">
@ -3921,7 +4067,6 @@ is used in the feature code. Consider the following, which also happens to be th
%feature("director:except") %{
jthrowable $error = jenv-&gt;ExceptionOccurred();
if ($error) {
jenv-&gt;ExceptionClear();
$directorthrowshandlers
Swig::DirectorException::raise(jenv, $error);
}
@ -3930,34 +4075,33 @@ is used in the feature code. Consider the following, which also happens to be th
</div>
<p>
where <tt>Swig::DirectorException::raise</tt> is a helper method in the DirectorException class to throw a C++ exception (implemented in director.swg):
</p>
<div class="code">
<pre>
static void raise(JNIEnv *jenv, jthrowable throwable) {
throw DirectorException(jenv, throwable);
}
</pre>
</div>
<p>The code generated using the <code>director:except</code> feature
replaces the <code>$directorthrowshandlers</code> special variable with the code in
the "directorthrows" typemaps, for each and every exception defined for the method.
The possible exceptions can be defined either with a C++ exception
where <tt>Swig::DirectorException::raise</tt> is the helper method to throw a C++ <tt>Swig::DirectorException</tt>, see above.
The code generated from the <code>director:except</code> feature
has the <code>$directorthrowshandlers</code> special variable replaced with the code in
the relevant "directorthrows" typemaps, for each and every exception defined for the method.
The relevant exceptions can be defined either with a C++ exception
specification or <code>%catches</code> as described for the
<a href="Typemaps.html#throws_typemap">"throws" typemap</a>.
</p>
<p>
Consider the following director method:
Let's try and put all this together by considering the following director method:
</p>
<div class="code">
<pre>
...
struct X {
virtual void doSomething(int index) throw (std::out_of_range);
...
};
OR
%catches(std::out_of_range) X::doSomething;
struct X {
virtual void doSomething(int index);
...
};
</pre>
</div>
@ -3970,11 +4114,9 @@ the resulting code generated in the director method after calling up to Java wil
<pre>
jthrowable swigerror = jenv-&gt;ExceptionOccurred();
if (swigerror) {
jenv-&gt;ExceptionClear();
if (Swig::ExceptionMatches(jenv, swigerror, "java/lang/IndexOutOfBoundsException")) {
throw std::out_of_range(Swig::JavaExceptionMessage(jenv, swigerror).message());
}
Swig::DirectorException::raise(jenv, swigerror);
}
</pre>
@ -3983,7 +4125,7 @@ if (swigerror) {
<p><em>
Note: Beware of using exception specifications as the SWIG director methods
will be generated with the same exception specifications and if the
director method throws an exception that is not specified it is likely
director method throws an exception that is not specified in the exception specifications list it is likely
to terminate your program. See the C++ standard for more details.
Using the %catches feature instead to define the handled exceptions does not suffer
this potential fate.
@ -3991,8 +4133,9 @@ this potential fate.
<p>Because the default code generation maps any unhandled Java exceptions to
<code>Swig::DirectorException</code>, any director methods that have exception
specifications may cause program termination. To simply ignore
unexpected exceptions, the default handling can be changed with:
specifications may cause program termination as this exception class won't be in the exception specifications list.
You can avoid throwing <tt>Swig::DirectorException</tt> by changing the default handling for all methods by adding a <tt>director:except</tt> feature without any method name.
For example, you can just ignore them:
</p>
<div class="code">
@ -4000,8 +4143,8 @@ unexpected exceptions, the default handling can be changed with:
%feature("director:except") %{
jthrowable $error = jenv-&gt;ExceptionOccurred();
if ($error) {
jenv-&gt;ExceptionClear();
$directorthrowshandlers
jenv-&gt;ExceptionClear();
return $null; // exception is ignored
}
%}
@ -4011,7 +4154,7 @@ unexpected exceptions, the default handling can be changed with:
<p>Alternatively an exception compatible with the existing director
method exception specifications can be thrown. Assuming that all
methods allow std::runtime_error to be thrown,
the <code>return&nbsp;$null;</code> could be changed to:
the <code>return&nbsp;$null</code> line above could be changed to:
</p>
<div class="code">
@ -4021,124 +4164,296 @@ the <code>return&nbsp;$null;</code> could be changed to:
</div>
<p>In more complex situations, a separate <code>director:except</code> feature
may need to be attached to specific methods.
may need to be attached to specific methods by providing a method name to the <tt>director:except</tt> feature.
</p>
<p>Below is a complete example demonstrating the use
of the "directorthrows" typemaps. In this example, a
generic "directorthrows" typemap is appropriate for all three exceptions - all
take single string constructors. If the exceptions had different constructors,
it would be necessary to have separate typemaps for each exception type.
<p>This is all no doubt quite hard to follow without seeing a full example and some code.
Below is a complete example demonstrating the use
of most of the exception customizations one can use, that is,
"directorthrows" and "throws" typemaps, %exception and %catches.
See the <a href="#Java_exception_handling">Exception handling with %exception and %javaexception</a>
section for more on converting C++ exceptions to Java exceptions.
The example also has a user defined C++ exception class called <tt>MyNS::MyException</tt> and this is wrapped as a Java exception.
The director class being wrapped is <tt>MyClass</tt> and the director method is called <tt>MyClass::dirmethod</tt>.
A number of <tt>std::cout</tt> calls have been added to help understand code flow.
You can copy the code below into an interface file and run SWIG on it and examine the generated code.
<!-- All the DEFINE_ and DECLARE_EXCEPTIONS CAN BE OMITTED to make
this more succinct. They are included to make this a complete
example interface that could be generated and built. -->
<div class="code">
<pre>
%module(directors="1") example
%{
#include &lt;string&gt;
#include &lt;stdexcept&gt;
#include &lt;iostream&gt;
%}
// Define exceptions in header section using std::runtime_error
%define DEFINE_EXCEPTION(NAME)
%{
namespace MyNS {
struct NAME : public std::runtime_error { NAME(const std::string &amp;what) : runtime_error(what) {} };
// Generic catch handler for all wrapped methods
%exception %{
try {
$action
} catch (const std::exception &amp;e) {
std::cout &lt;&lt; "Generic std::exception catch handler" &lt;&lt; std::endl;
jclass clazz = jenv-&gt;FindClass("java/lang/RuntimeException");
jenv-&gt;ThrowNew(clazz, e.what());
return $null;
}
%}
%enddef
// Expose C++ exceptions as Java Exceptions by changing the Java base class and providing a getMessage()
%define DECLARE_EXCEPTION(NAME)
%typemap(javabase) MyNS::NAME "java.lang.Exception";
%rename(getMessage) MyNS::NAME::what;
// Expose C++ exception as a Java Exception by changing the Java base class and providing a getMessage()
%typemap(javabase) MyNS::MyException "java.lang.RuntimeException";
%rename(getMessage) MyNS::MyException::whatsup;
%inline %{
namespace MyNS {
struct NAME {
NAME(const std::string&amp; what);
const char * what();
class MyException {
std::string msg;
public:
MyException(const char *msg) : msg(msg) {}
const char * whatsup() const { return msg.c_str(); }
};
}
%enddef
DEFINE_EXCEPTION(ExceptionA)
DEFINE_EXCEPTION(ExceptionB)
DEFINE_EXCEPTION(Unexpected)
// Mark three methods to map director thrown exceptions.
%feature("director:except") MyClass::meth1(int);
%feature("director:except") MyClass::meth2;
%feature("director:except") meth3;
%typemap(directorthrows) MyNS::ExceptionA, MyNS::ExceptionB, MyNS::Unexpected %{
if (Swig::ExceptionMatches(jenv, $error, "$packagepath/$javaclassname"))
throw $1_type(Swig::JavaExceptionMessage(jenv, $error).message());
%}
DECLARE_EXCEPTION(ExceptionA)
DECLARE_EXCEPTION(ExceptionB)
DECLARE_EXCEPTION(Unexpected)
%typemap(directorthrows) MyNS::MyException %{
if (Swig::ExceptionMatches(jenv, $error, "$packagepath/MyException")) {
std::cout &lt;&lt; "$1_type exception matched (directorthrows typemap)" &lt;&lt; std::endl;
throw $1_type(Swig::JavaExceptionMessage(jenv, $error).message());
}
%}
%catches(MyNS::ExceptionA, MyNS::ExceptionB, MyNS::Unexpected) MyClass::meth2();
%typemap(throws) MyNS::MyException %{
std::cout &lt;&lt; "$1_type caught (throws typemap)" &lt;&lt; std::endl;
jclass excep = jenv-&gt;FindClass("MyException");
if (excep) {
std::cout &lt;&lt; "$1_type class found (throws typemap)" &lt;&lt; std::endl;
jenv-&gt;ThrowNew(excep, $1.whatsup());
}
return $null;
%}
%inline {
class MyClass {
public:
virtual void meth1(int x) throw(MyNS::ExceptionA, MyNS::ExceptionB) = 0;
virtual void meth2() = 0; /* throws MyNS::ExceptionA, MyNS::ExceptionB, MyNS::Unexpected */
virtual void meth3(float x) throw(MyNS::Unexpected) = 0;
virtual ~MyClass() {}
};
// These are the exceptions that the director method MyClass::dirmethod will have catch handlers for.
// Note that this is also a virtual method / director method and the C++ exceptions listed can be
// thrown after converting them from Java exceptions.
%catches(MyNS::MyException, Swig::DirectorException) MyClass::dirmethod;
// These are the exceptions that call_dirmethod C++ wrapper will have catch handlers for.
// Note that this is not a virtual method, hence not a director method.
%catches(MyNS::MyException, Swig::DirectorException) call_dirmethod;
%feature("director") MyClass;
%feature("director:except") MyClass::dirmethod(int x) {
jthrowable $error = jenv-&gt;ExceptionOccurred();
if ($error) {
std::cout &lt;&lt; "Upcall finished, an exception was thrown in Java" &lt;&lt; std::endl;
$directorthrowshandlers
std::cout &lt;&lt; "Upcall finished, no exception conversion, throwing DirectorException" &lt;&lt; std::endl;
Swig::DirectorException::raise(jenv, $error);
}
}
%inline %{
class MyClass {
public:
/** Throws either a std::out_of_range or MyException on error */
virtual void dirmethod(int x) {
if (x &lt;= 0)
throw std::out_of_range("MyClass::dirmethod index is out of range");
else if (x == 1)
throw MyNS::MyException("MyClass::dirmethod some problem!");
}
virtual ~MyClass() {}
static void call_dirmethod(MyClass&amp; c, int x) {
return c.dirmethod(x);
}
};
%}
</pre>
</div>
<p>
In this case the three different "directorthrows" typemaps will be used
to generate the three different exception handlers for
<code>meth1</code>, <code>meth2</code> and <code>meth3</code>. The generated
handlers will have "if" blocks for each exception type specified, in
the exception specification or <code>%catches</code> feature.
</p>
<p>Note that the "directorthrows" typemaps are important
only if it is important for the exceptions passed through the C++
layer to be mapped to distinct C++ exceptions. If director methods
are being called by C++ code that is itself wrapped in a
SWIG generated Java wrapper and access is always through this wrapper,
the default <code>Swig::DirectorException</code> class provides enough information
to reconstruct the original exception. In this case removing the
<code>$directorthrowshandlers</code> special variable from the
default <code>director:except</code> feature and simply always
throwing a <code>Swig::DirectorException</code> will achieve the desired result.
Along with this a generic exception feature is added to convert any
caught <code>Swig::DirectorException</code>s back into the underlying
Java exceptions via the <code>Swig::DirectorException::raiseJavaException</code> method,
as demonstrated with <code>%javaexception</code> below:
The generated code for the <tt>call_dirmethod</tt> wrapper contains the various exception handlers.
The outer exception handler is from the <tt>%exception</tt> directive and the others
are from the "throws" typemaps.
</p>
<div class="code">
<pre>
%javaexception("Exception") MyClass::myMethod %{
SWIGEXPORT void JNICALL Java_exampleJNI_MyClass_1call_1dirmethod(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2) {
...
try {
$action
} catch (Swig::DirectorException &amp;e) {
// raise/throw the Java exception that originally caused the DirectorException
e.raiseJavaException(jenv);
return $null;
try {
MyClass::call_dirmethod(*arg1,arg2);
} catch(MyNS::MyException &amp;_e) {
std::cout &lt;&lt; "MyNS::MyException caught (throws typemap)" &lt;&lt; std::endl;
jclass excep = jenv-&gt;FindClass("MyException");
if (excep) {
std::cout &lt;&lt; "MyNS::MyException class found (throws typemap)" &lt;&lt; std::endl;
jenv-&gt;ThrowNew(excep, (&amp;_e)-&gt;whatsup());
}
return ;
} catch(Swig::DirectorException &amp;_e) {
(&amp;_e)-&gt;throwException(jenv);
return ;
}
} catch (const std::exception &amp;e) {
std::cout &lt;&lt; "Generic std::exception catch handler" &lt;&lt; std::endl;
jclass clazz = jenv-&gt;FindClass("java/lang/RuntimeException");
jenv-&gt;ThrowNew(clazz, e.what());
return ;
}
%}
</pre>
</div>
<p>
See the <a href="#Java_exception_handling">Exception handling with %exception and %javaexception</a>
section for more on converting C++ exceptions to Java exceptions.
The director method calling up to Java contains the exception handling code from the "directorthrows" typemaps and <tt>director:except</tt> feature.
</p>
<div class="code">
<pre>
void SwigDirector_MyClass::dirmethod(int x) {
... [call up to Java using CallStaticVoidMethod]
jthrowable swigerror = jenv-&gt;ExceptionOccurred();
if (swigerror) {
std::cout &lt;&lt; "Upcall finished, an exception was thrown in Java" &lt;&lt; std::endl;
if (Swig::ExceptionMatches(jenv, swigerror, "MyException")) {
std::cout &lt;&lt; "MyNS::MyException exception matched (directorthrows typemap)" &lt;&lt; std::endl;
throw MyNS::MyException(Swig::JavaExceptionMessage(jenv, swigerror).message());
}
std::cout &lt;&lt; "Upcall finished, no exception conversion, throwing DirectorException" &lt;&lt; std::endl;
Swig::DirectorException::raise(jenv, swigerror);
}
</pre>
</div>
<p>
Let's use the following Java class to override the director method.
</p>
<div class="code">
<pre>
class DerivedClass extends MyClass {
@Override
public void dirmethod(int x) {
if (x &lt; 0)
throw new IndexOutOfBoundsException("Index is negative");
else if (x == 0)
throw new MyException("MyException: bad dirmethod");
}
}
public class runme {
public static void main(String argv[]) {
System.loadLibrary("example");
... code snippets shown below ...
}
}
</pre>
</div>
<p>
Consider the output using the Java code in the four slightly different scenarios below.
</p>
<p>
1. Non-director C++ class is used, thus, no upcall to a Java director method is made.
A <tt>std::out_of_range</tt> exception is thrown, which is derived from <tt>std::exception</tt>,
and hence caught by the generic exception handler in the <tt>call_dirmethod</tt> wrapper.
The Java code snippet and resulting output is:
</p>
<div class="code">
<pre>
MyClass.call_dirmethod(new MyClass(), 0);
</pre>
</div>
<div class="shell">
<pre>
Generic std::exception catch handler
Exception in thread "main" java.lang.RuntimeException: MyClass::dirmethod index is out of range
at exampleJNI.MyClass_call_dirmethod(Native Method)
at MyClass.call_dirmethod(MyClass.java:57)
at runme.main(runme.java:14)
</pre>
</div>
<p>
2. Non-director C++ class again but this time the <tt>MyNS::MyException</tt> class is thrown and caught:
</p>
<div class="code">
<pre>
MyClass.call_dirmethod(new MyClass(), 1);
</pre>
</div>
<div class="shell">
<pre>
MyNS::MyException caught (throws typemap)
MyNS::MyException class found (throws typemap)
Exception in thread "main" MyException: MyClass::dirmethod some problem!
at exampleJNI.MyClass_call_dirmethod(Native Method)
at MyClass.call_dirmethod(MyClass.java:57)
at runme.main(runme.java:15)
</pre>
</div>
<p>
3. The <tt>DerivedClass</tt> director class is used so the upcall to Java occurs, but it throws
a Java <tt>MyException</tt>, which gets converted into a C++ <tt>MyNS::MyException</tt>, then caught and converted back
into a Java <tt>MyException</tt>:
</p>
<div class="code">
<pre>
MyClass.call_dirmethod(new DerivedClass(), 0);
</pre>
</div>
<div class="shell">
<pre>
Upcall finished, an exception was thrown in Java
MyNS::MyException exception matched (directorthrows typemap)
MyNS::MyException caught (throws typemap)
MyNS::MyException class found (throws typemap)
Exception in thread "main" MyException: MyException: bad dirmethod
at exampleJNI.MyClass_call_dirmethod(Native Method)
at MyClass.call_dirmethod(MyClass.java:57)
at runme.main(runme.java:16)
</pre>
</div>
<p>
4. The director class is used again, but this time the director method throws a Java <tt>IndexOutOfBoundsException</tt> exception which is converted into a C++ <tt>Swig::DirectorException</tt>, thrown and caught again.
This time the original Java exception is extracted from the <tt>Swig::DirectorException</tt> and rethrown.
Note that this approach keeps the stack trace information of the original exception, so it has the exact location of where the <tt>IndexOutOfBoundsException</tt> exception was thrown.
This is arguably an improvement over the approach above that converts from a Java excepton to C++ exception and then back to a new Java exception, losing the location of the original exception.
</p>
<div class="code">
<pre>
MyClass.call_dirmethod(new DerivedClass(), -1);
</pre>
</div>
<div class="shell">
<pre>
Upcall finished, an exception was thrown in Java
Upcall finished, no exception conversion, throwing DirectorException
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index is negative
at DerivedClass.dirmethod(runme.java:5)
at exampleJNI.SwigDirector_MyClass_dirmethod(exampleJNI.java:23)
at exampleJNI.MyClass_call_dirmethod(Native Method)
at MyClass.call_dirmethod(MyClass.java:57)
at runme.main(runme.java:17)
</pre>
</div>
<H2><a name="Java_allprotected">25.6 Accessing protected members</a></H2>
@ -8165,40 +8480,52 @@ public class Container {
// Ensure that the GC doesn't collect any Element set from Java
// as the underlying C++ class stores a shallow copy
private Element elementReference;
private long getCPtrAndAddReference(Element element) {
elementReference = element;
return Element.getCPtr(element);
}
public void setElement(Element e) {
exampleJNI.Container_setElement(swigCPtr, this, getCPtrAndAddReference(e), e);
exampleJNI.Container_setElement(swigCPtr, this, Element.getCPtr(e), e);
elementReference = e;
}
}
</pre>
</div>
<p>
The following typemaps will generate the desired code.
The 'javain' typemap matches the input parameter type for the <tt>setElement</tt> method.
The 'javacode' typemap simply adds in the specified code into the Java proxy class.
The following typemaps can be used to generate this code:
</p>
<div class="code">
<pre>
%typemap(javain) Element *e "getCPtrAndAddReference($javainput)"
%typemap(javacode) Container %{
// Ensure that the GC doesn't collect any element set from Java
// as the underlying C++ class stores a shallow copy
private Element elementReference;
private long getCPtrAndAddReference(Element element) {
elementReference = element;
return Element.getCPtr(element);
}
%}
%typemap(javain,
post=" elementReference = $javainput;"
) Element *e "Element.getCPtr($javainput)"
</pre>
</div>
<p>
The 'javacode' typemap simply adds in the specified code into the Java proxy class.
The 'javain' typemap matches the input parameter type and name for the <tt>setElement</tt> method and
the 'post' typemap attribute allows adding code after the JNI call.
The 'post' code is generated into a finally block after the JNI call so the resulting code isn't quite
as mentioned earlier, <tt>setElement</tt> is actually:
</p>
<div class="code">
<pre>
public void setElement(Element e) {
try {
exampleJNI.Container_setElement(swigCPtr, this, Element.getCPtr(e), e);
} finally {
elementReference = e;
}
}
</pre>
</div>
<H3><a name="Java_date_marshalling">25.10.13 Date marshalling using the javain typemap and associated attributes</a></H3>

View file

@ -35,6 +35,7 @@
<ul>
<li><a href="#Library_shared_ptr_basics">shared_ptr basics</a>
<li><a href="#Library_shared_ptr_inheritance">shared_ptr and inheritance</a>
<li><a href="#Library_shared_ptr_overloading">shared_ptr and method overloading</a>
<li><a href="#Library_shared_ptr_templates">shared_ptr and templates</a>
<li><a href="#Library_shared_ptr_directors">shared_ptr and directors</a>
</ul>
@ -419,11 +420,11 @@ Now, in a scripting language, you might write this:
<div class="targetlang">
<pre>
a = new_doubleArray(10) # Create an array
a = new_doubleArray(10) # Create an array
for i in range(0, 10):
doubleArray_setitem(a, i, 2*i) # Set a value
print_array(a) # Pass to C
delete_doubleArray(a) # Destroy array
doubleArray_setitem(a, i, 2 * i) # Set a value
print_array(a) # Pass to C
delete_doubleArray(a) # Destroy array
</pre>
</div>
@ -486,7 +487,7 @@ Allows you to do this:
import example
c = example.doubleArray(10) # Create double[10]
for i in range(0, 10):
c[i] = 2*i # Assign values
c[i] = 2 * i # Assign values
example.print_array(c) # Pass to C
</pre>
</div>
@ -502,6 +503,7 @@ you should consider using a special array object rather than a bare pointer.
<p>
<b>Note:</b> <tt>%array_functions()</tt> and <tt>%array_class()</tt> should not be
used with types of <tt>char</tt> or <tt>char *</tt>.
SWIG's default handling of these types is to handle them as character strings and the two macros do not do enough to change this.
</p>
<H3><a name="Library_nn6">9.2.3 cmalloc.i</a></H3>
@ -1474,7 +1476,7 @@ In the target language:
<div class="targetlang">
<pre>
x = my_struct();
x.foo="Hello World"; # assign with string
x.foo = "Hello World"; # assign with string
print x.foo; # print as string
</pre>
</div>
@ -1921,7 +1923,30 @@ Adding the missing <tt>%shared_ptr</tt> macros will fix this:
</pre>
</div>
<H4><a name="Library_shared_ptr_templates">9.4.4.3 shared_ptr and templates</a></H4>
<H4><a name="Library_shared_ptr_overloading">9.4.4.3 shared_ptr and method overloading</a></H4>
<p>
A C++ compiler can disambiguate a method overloaded by a shared_ptr and one using the raw underlying type.
For example, either one of these methods can be called in C++:
</p>
<div class="code">
<pre>
int age(std::shared_ptr&lt;GrandParent&gt; num);
int age(GrandParent&amp; num);
</pre>
</div>
<p>
When wrapped by SWIG, disambiguation is not possible using the overloaded names as there is just one equivalent type (<tt>GrandParent</tt>) in the target language.
SWIG will choose to wrap just the first method by default.
<a href="SWIGPlus.html#SWIGPlus_nn25">Ambiguity in overloading</a> discusses ways to control which method(s) gets wrapped using <tt>%ignore</tt> or <tt>%rename</tt>.
For the interested reader, SWIG detects that they are equivalent types via the <a href=Typemaps.html#Typemaps_typecheck_pointer>typecheck typemaps</a> in the shared_ptr library.
</p>
<H4><a name="Library_shared_ptr_templates">9.4.4.4 shared_ptr and templates</a></H4>
<p>
The <tt>%shared_ptr</tt> macro should be used for all the required instantiations
@ -1962,13 +1987,11 @@ The SWIG code below shows the required ordering:
</pre>
</div>
<H4><a name="Library_shared_ptr_directors">9.4.4.4 shared_ptr and directors</a></H4>
<H4><a name="Library_shared_ptr_directors">9.4.4.5 shared_ptr and directors</a></H4>
<p>
There is somewhat limited support for <tt>%shared_ptr</tt> and the director feature
and the degrees of success varies among the different target languages.
Please help to improve this support by providing patches with improvements.
The languages that support shared_ptr also have support for using shared_ptr with directors.
</p>

View file

@ -6521,14 +6521,16 @@ string that cannot be completely decoded as UTF-8:
<div class="code"><pre>
%module example
%include &lt;std_string.i&gt;
%inline %{
const char* non_utf8_c_str(void) {
const char * non_utf8_c_str(void) {
return "h\xe9llo w\xc3\xb6rld";
}
void instring(const char *s) {
...
}
%}
</pre></div>
@ -6590,6 +6592,20 @@ For more details about the <tt>surrogateescape</tt> error handler, please see
<a href="https://www.python.org/dev/peps/pep-0383/">PEP 383</a>.
</p>
<p>
When Python 3 strings are passed to the C/C++ layer, they are expected to be valid UTF8 Unicode strings too.
For example, when the <tt>instring</tt> method above is wrapped and called, any invalid UTF8 Unicode code strings
will result in a TypeError because the attempted conversion fails:
</p>
<div class="targetlang"><pre>
&gt;&gt;&gt; example.instring('h\xe9llo')
&gt;&gt;&gt; example.instring('h\udce9llo')
Traceback (most recent call last):
File "&lt;stdin&gt;", line 1, in &lt;module&gt;
TypeError: in method 'instring', argument 1 of type 'char const *'
</pre></div>
<p>
In some cases, users may wish to instead handle all byte strings as bytes
objects in Python 3. This can be accomplished by adding

View file

@ -3343,7 +3343,7 @@ SWIG_From_float(float)</td>
<p>Here, while the Ruby versions return the value directly, the SWIG
versions do not, but return a status value to indicate success (<tt>SWIG_OK</tt>). While more akward to use, this allows you to write typemaps that report more helpful error messages, like:</p>
versions do not, but return a status value to indicate success (<tt>SWIG_OK</tt>). While more awkward to use, this allows you to write typemaps that report more helpful error messages, like:</p>
<div class="code">
<pre>

View file

@ -163,6 +163,32 @@ can be obtained by typing <tt>swig -help</tt> or <tt>swig
</pre></div>
<p>
Arguments may also be passed in a command-line options file (also known as a
response file) which is useful if they exceed the system command line length
limit. To do this, put the arguments in a file, then provide the file name
prefixed with <tt>@</tt> like so:
</p>
<div class="shell"><pre>
swig @<em>file</em>
</pre></div>
<p>
The options read from the file are inserted in place of the file option. If the
file does not exist, or cannot be read, then the option will be treated
literally and not removed.
</p>
<p>
Options in the file are separated by whitespace. A whitespace character may be
included in an option by surrounding the entire option in either single or
double quotes. Any character (including a backslash) may be included by
prefixing the character to be included with a backslash. The file may itself
contain additional <tt>@file</tt> options; any such options will be processed
recursively.
</p>
<H3><a name="SWIG_nn3">5.1.1 Input format</a></H3>
@ -2177,7 +2203,7 @@ in the C++ chapter for further details.
<p>
Occasionally, a C library may include functions that expect to receive
pointers to functions--possibly to serve as callbacks. SWIG
provides full support for function pointers provided that the callback
provides full support for function pointers when the callback
functions are defined in C and not in the target language. For example,
consider a function like this:
</p>
@ -2321,7 +2347,9 @@ And now, a final note about function pointer support. Although SWIG
does not normally allow callback functions to be written in the target language, this
can be accomplished with the use of typemaps and other advanced SWIG features.
See the <a href="Typemaps.html#Typemaps">Typemaps chapter</a> for more about typemaps
and individual target language chapters for more on callbacks and the 'director' feature.
and individual target language chapters for more on callbacks.
The 'director' feature can be used to make callbacks from C/C++ into the target language,
see <a href="SWIGPlus.html#SWIGPlus_target_language_callbacks">Callbacks to the target language</a>.
</p>
<H2><a name="SWIG_nn31">5.5 Structures and unions</a></H2>

View file

@ -72,6 +72,11 @@
<li><a href="#SWIGPlus_nn35">Using declarations and inheritance</a>
<li><a href="#SWIGPlus_nested_classes">Nested classes</a>
<li><a href="#SWIGPlus_const">A brief rant about const-correctness</a>
<li><a href="#SWIGPlus_target_language_callbacks">Callbacks to the target language</a>
<ul>
<li><a href="#SWIGPlus_director_classes_introduction">Introduction to director classes</a>
<li><a href="#SWIGPlus_directors_for_function_pointers">Using directors and target language callbacks</a>
</ul>
<li><a href="#SWIGPlus_nn42">Where to go for more information</a>
</ul>
</div>
@ -80,7 +85,10 @@
<p>
This chapter describes SWIG's support for wrapping C++. As a prerequisite,
This chapter describes SWIG's support for wrapping C++.
It is mostly concerned about C++ as defined by the C++ 98 and 03 standards.
For C++ 11 features please read the <a href="CPlusPlus11.html">SWIG and C++11</a> chapter.
As a prerequisite,
you should first read the chapter <a href="SWIG.html#SWIG">SWIG Basics</a> to see
how SWIG wraps ANSI C. Support for C++ builds upon ANSI C
wrapping and that material will be useful in understanding this chapter.
@ -3144,7 +3152,7 @@ redundant and will simply result in code bloat).
</p>
<p>
The template provide to <tt>%template</tt> for instantiation must be the actual template and not a typedef to a template.
The template provided to <tt>%template</tt> for instantiation must be the actual template and not a typedef to a template.
</p>
<div class="code">
@ -4622,7 +4630,7 @@ The next section details a way of simulating an exception specification or repla
Exceptions are automatically handled for methods with an exception specification.
Similar handling can be achieved for methods without exception specifications through the <tt>%catches</tt> feature.
It is also possible to replace any declared exception specification using the <tt>%catches</tt> feature.
In fact, <tt>%catches</tt> uses the same <a href="Typemaps.html#throws_typemap">"throws" typemaps</a> that SWIG uses for exception specifications in handling exceptions.
In fact, <tt>%catches</tt> uses the same <a href="Typemaps.html#Typemaps_throws_typemap">"throws" typemaps</a> that SWIG uses for exception specifications in handling exceptions.
The <tt>%catches</tt> feature must contain a list of possible types that can be thrown.
For each type that is in the list, SWIG will generate a catch handler, in the same way that it would for types declared in the exception specification.
Note that the list can also include the catch all specification "...".
@ -5385,7 +5393,152 @@ using another tool if maintaining constness is the most important part
of your project.
</p>
<H2><a name="SWIGPlus_nn42">6.29 Where to go for more information</a></H2>
<H2><a name="SWIGPlus_target_language_callbacks">6.29 Callbacks to the target language</a></H2>
<p>
C/C++ function pointers are often used for callbacks and this is discussed in the
<a href="SWIG.html#SWIG_nn30">Pointers to functions and callbacks</a> section.
The callback techniques described therein provide a way to control callbacks to a C/C++ function but not callbacks into the target language.
The techniques described below show how the director feature can be used to support callbacks from C/C++ to the target language.
</p>
<H3><a name="SWIGPlus_director_classes_introduction">6.29.1 Introduction to director classes</a></H3>
<p>
The director feature enables the ability for a target language class to derive from a wrapped C++ class.
The target language can override virtual methods of a wrapped C++ class, thereby supporting cross-language polymorphism.
Code can 'call up' from C++ into the target language by simply calling a virtual method overridden in a derived class in the target language.
The wrapped C++ classes that have this ability are termed 'director' classes.
The director feature is documented individually in each target language and the reader should locate and read this to obtain a full understanding of directors.
</p>
<H3><a name="SWIGPlus_directors_for_function_pointers">6.29.2 Using directors and target language callbacks</a></H3>
<p>
SWIG's primary goal is to make it possible to call C/C++ code from a target language, however, the director feature enables the reverse.
While there isn't simple direct support for calling target language code from C, the director feature makes this possible.
It does require some work and additional wrapper code to be provided by the user.
The additional code required must be C++ and not C code and hence may introduce a small dependency on C++ if using a pure C project.
In a nutshell, the user must create a C++ base class and turn it into a director class.
A virtual method in the director base class is required.
SWIG generates the code to call up into the target language when wrapping the director virtual method.
</p>
<p>
Let's look at some details next.
Consider the same function pointer for a callback called <tt>binary_op</tt> from the
<a href="SWIG.html#SWIG_nn30">Pointers to functions and callbacks</a> section.
For completeness, the code required for the module and director feature is also shown:
</p>
<div class="code"><pre>
%module(directors="1") example
%{
int binary_op(int a, int b, int (*op)(int, int)) {
return op(a, b);
}
%}
</pre></div>
<p>
The goal is to have a target language function that gets called by <tt>binary_op</tt>.
The target language function should have the equivalent signature as the C/C++ function pointer <tt>int (*op)(int, int)</tt>.
As we are using directors, we need a C++ virtual method with this signature, so let's
define the C++ class and pure virtual method first and make it a director class via the
director feature:
</p>
<div class="code"><pre>
%feature("director") BinaryOp;
%inline %{
struct BinaryOp {
virtual int handle(int a, int b) = 0;
virtual ~BinaryOp() {}
};
%}
</pre></div>
<p>
The following <tt>handler_helper</tt> function and <tt>binary_op_wrapper</tt> function completes the code needed in the
C++/SWIG layer. The <tt>binary_op_wrapper</tt> function is wrapped by SWIG and is very similar to the <tt>binary_op</tt> function,
however, it takes a pointer to the director base class <tt>BinaryOp</tt> instead of a C/C++ function pointer.
</p>
<div class="code"><pre>
%{
static BinaryOp *handler_ptr = NULL;
static int handler_helper(int a, int b) {
// Make the call up to the target language when handler_ptr
// is an instance of a target language director class
return handler_ptr-&gt;handle(a, b);
}
// If desired, handler_ptr above could be changed to a thread-local variable in order to make thread-safe
%}
%inline %{
int binary_op_wrapper(int a, int b, BinaryOp *handler) {
handler_ptr = handler;
int result = binary_op(a, b, &amp;handler_helper);
handler = NULL;
return result;
}
%}
</pre></div>
<p>
On the target language side, we need to derive a class from <tt>BinaryOp</tt> and override the
<tt>handle</tt> method. In Python this could be as simple as:
</p>
<div class="targetlang">
<pre>
import example
# PythonBinaryOp class is defined and derived from C++ class BinaryOp
class PythonBinaryOp(example.BinaryOp):
# Define Python class 'constructor'
def __init__(self):
# Call C++ base class constructor
example.BinaryOp.__init__(self)
# Override C++ method: virtual int handle(int a, int b) = 0;
def handle(self, a, b):
# Return the product
return a * b
</pre>
</div>
<p>
For this to work from Python, an instance of the <tt>PythonBinaryOp</tt> class is created
and then passed to <tt>binary_op_wrapper</tt>. The net result is the <tt>binary_op</tt>
function will in turn be called which will call <tt>handler_helper</tt> which will call
the virtual <tt>handle</tt> method, that is, the Python method <tt>handle</tt> in the PythonBinaryOp class. The result will be the product of 10 and 20 and make its way back to Python and hence
200 will be printed with the following code:
</p>
<div class="targetlang">
<pre>
handler = PythonBinaryOp()
result = example.binary_op_wrapper(10, 20, handler)
print result
</pre>
</div>
<p>
This has thus demonstrated a C/C++ function pointer calling back into a target language function.
The code could be made a little more user friendly by using <tt>%rename</tt> to provide the
original <tt>binary_op</tt> name from the target language instead of <tt>binary_op_wrapper</tt>.
A C++ functor base class and Python functor class
could also be used instead, but these are left as exercises for the reader.
</p>
<H2><a name="SWIGPlus_nn42">6.30 Where to go for more information</a></H2>
<p>

View file

@ -67,7 +67,7 @@
<li><a href="#Typemaps_nn35">"memberin" typemap</a>
<li><a href="#Typemaps_nn36">"varin" typemap</a>
<li><a href="#Typemaps_nn37">"varout" typemap</a>
<li><a href="#throws_typemap">"throws" typemap</a>
<li><a href="#Typemaps_throws_typemap">"throws" typemap</a>
</ul>
<li><a href="#Typemaps_nn39">Some typemap examples</a>
<ul>
@ -89,6 +89,9 @@
<li><a href="#Typemaps_runtime_type_checker_usage">Usage</a>
</ul>
<li><a href="#Typemaps_overloading">Typemaps and overloading</a>
<ul>
<li><a href="#Typemaps_typecheck_pointer">SWIG_TYPECHECK_POINTER precedence level and the typecheck typemap</a>
</ul>
<li><a href="#Typemaps_nn48">More about %apply and %clear</a>
<li><a href="#Typemaps_nn47">Passing data between typemaps</a>
<li><a href="#Typemaps_nn52">C++ "this" pointer</a>
@ -2881,11 +2884,11 @@ The "varout" typemap is used to convert a C/C++ object to an object in the targe
language when reading a C/C++ global variable. This is implementation specific.
</p>
<H3><a name="throws_typemap">11.5.14 "throws" typemap</a></H3>
<H3><a name="Typemaps_throws_typemap">11.5.14 "throws" typemap</a></H3>
<p>
The "throws" typemap is only used when SWIG parses a C++ method with an exception specification or has the <tt>%catches</tt> feature attached to the method.
The "throws" typemap is only used when SWIG parses a C++ method with an exception specification or has the <tt>%catches</tt> feature attached to the method (see <a href="SWIGPlus.html#SWIGPlus_catches">Exception handling with %catches</a>).
It provides a default mechanism for handling C++ methods that have declared the exceptions they will throw.
The purpose of this typemap is to convert a C++ exception into an error or exception in the target language.
It is slightly different to the other typemaps as it is based around the exception type rather than the type of a parameter or variable.
@ -2898,13 +2901,19 @@ For example:
PyErr_SetString(PyExc_RuntimeError, $1);
SWIG_fail;
%}
void bar() throw (const char *);
// Either an exception specification on the method
void bar() throw (const char *);
// Or a %catches feature attached to the method
%catches(const char *) bar();
void bar();
</pre>
</div>
<p>
As can be seen from the generated code below, SWIG generates an exception handler
with the catch block comprising the "throws" typemap content.
As can be seen from the resulting generated code below, SWIG generates an exception handler
when wrapping the <tt>bar</tt> function with the catch block comprising the "throws" typemap content.
</p>
<div class="code">
@ -2912,8 +2921,7 @@ with the catch block comprising the "throws" typemap content.
...
try {
bar();
}
catch(char const *_e) {
} catch(char const *_e) {
PyErr_SetString(PyExc_RuntimeError, _e);
SWIG_fail;
}
@ -2922,8 +2930,8 @@ catch(char const *_e) {
</div>
<p>
Note that if your methods do not have an exception specification yet they do throw exceptions, SWIG cannot know how to deal with them.
For a neat way to handle these, see the <a href="Customization.html#Customization_exception">Exception handling with %exception</a> section.
Note that if your methods do not have an exception specification but they do throw exceptions and you are not using <tt>%catches</tt>, SWIG cannot know how to deal with them.
Please also see the <a href="Customization.html#Customization_exception">Exception handling with %exception</a> section for another way to handle exceptions.
</p>
<H2><a name="Typemaps_nn39">11.6 Some typemap examples</a></H2>
@ -4754,7 +4762,8 @@ then the type is given a precedence higher than any other known precedence level
<div class="shell">
<pre>
example.i:18: Warning 467: Overloaded method foo(int) not supported (incomplete type checking rule - no precedence level in typecheck typemap for 'int').
example.i:18: Warning 467: Overloaded method foo(int) not supported (incomplete type
checking rule - no precedence level in typecheck typemap for 'int').
</pre>
</div>
@ -4779,10 +4788,112 @@ simply check the type of the first array element and use that to dispatch to the
Subsequent "in" typemaps would then perform more extensive type-checking.
</li>
<li>Make sure you read the section on overloading in the "<a href="SWIGPlus.html#SWIGPlus">SWIG and C++</a>" chapter.
<li>Make sure you read the section on <a href="SWIGPlus.html#SWIGPlus_overloaded_methods">overloading</a> in the SWIG and C++ chapter.
</li>
</ul>
<H3><a name="Typemaps_typecheck_pointer">11.13.1 SWIG_TYPECHECK_POINTER precedence level and the typecheck typemap</a></H3>
<p>
When it comes to overloading of a particular type passed by value, pointer or reference (const and non-const),
a C++ compiler can disambiguate which overloaded function to call.
However, SWIG effectively treats these as pointers in the target language and thus as equivalent types.
For example, consider:
</p>
<div class="code">
<pre>
class X { ... };
void m(X const &amp;c); // equivalent: void m(X *c);
void m(X &amp;r); // equivalent: void m(X *r);
void m(X *p); // equivalent: void m(X *p);
</pre>
</div>
<p>
These cannot be disambiguated in the target languages and so SWIG will choose the first method and ignore the subsequent two methods.
The scripting languages do this by using the overload dispatch mechanism described earlier and warnings indicate this:
</p>
<div class="shell">
<pre>
example.i:6: Warning 509: Overloaded method m(X &amp;) effectively ignored,
example.i:5: Warning 509: as it is shadowed by m(X const &amp;).
example.i:7: Warning 509: Overloaded method m(X *) effectively ignored,
example.i:5: Warning 509: as it is shadowed by m(X const &amp;).
</pre>
</div>
<p>
The statically typed languages like Java and C# automatically ignore all but the first equivalent overloaded methods with warnings:
</p>
<div class="shell">
<pre>
example.i:6: Warning 516: Overloaded method m(X &amp;) ignored,
example.i:5: Warning 516: using m(X const &amp;) instead.
example.i:7: Warning 516: Overloaded method m(X *) ignored,
example.i:5: Warning 516: using m(X const &amp;) instead.
</pre>
</div>
<p>
You can select the overloaded method you would like to wrap by ignoring the other two with <tt>%ignore</tt> or rename two of them with <tt>%rename</tt>
and this will of course remove the warnings too.
The problem of ambiguity is also discussed in the C++ chapter on <a href="SWIGPlus.html#SWIGPlus_overloaded_methods">overloading</a>.
</p>
<p>
So how does this work with respect to typemaps?
The typemaps SWIG provides to handle overloading for these three methods are from the SWIGTYPE family.
As discussed earlier, in <a href="Typemaps.html#Typemaps_nn19">Default typemap matching rules</a>,
the <tt>SWIGTYPE &amp;</tt> typemaps are used for references and <tt>SWIGTYPE *</tt> typemaps are used for pointers.
SWIG uses the special <tt>SWIG_TYPECHECK_POINTER</tt> (0) precedence level to handle these types in the "typecheck" typemap:
</p>
<div class="code">
<pre>
%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER) SWIGTYPE &amp; "..."
%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER) SWIGTYPE * "..."
</pre>
</div>
<p>
When the SWIGTYPE "typecheck" typemaps use the <tt>SWIG_TYPECHECK_POINTER</tt> precedence level,
SWIG converts the type to a pointer equivalent type and then uses the equivalent type to detect if it can be disambiguated in an overloaded method in the target language.
In our example above, the equivalent types for <tt>X const &amp;</tt>, <tt>X &amp;</tt> and <tt>X *</tt> are all <tt>X *</tt>.
As they are the same, they cannot be disambiguated and so just the first overloaded method is chosen.
</p>
<p>
The automatic conversion to equivalent types and subsequent type comparison is triggered via the use of the special <tt>SWIG_TYPECHECK_POINTER</tt> precedence level
and works for types passed by value, pointer and reference.
Alas, there are more ways to overload a method that also need handling.
C++ smart pointers are such a type which can be disambiguated by a C++ compiler but not automatically by SWIG.
SWIG does not automatically know that a smart pointer has an equivalent type, but it can be told manually.
Just specify the 'equivalent' attribute in the "typecheck" typemap with a pointer to the underlying type.
</p>
<div class="code">
<pre>
%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="X *") MySmartPtr&lt;X&gt; " ... "
void m(X &amp;r); // equivalent: void m(X *r);
void m(MySmartPtr&lt;X&gt; s); // equivalent: void m(X *s);
</pre>
</div>
<p>
Now SWIG will detect the two types are equivalent and generate valid code by wrapping just the first overloaded method.
You can of course choose which method to wrap by ignoring one of them with <tt>%ignore</tt>.
Otherwise both can be wrapped by removing the overloading name ambiguity by renaming one of them with <tt>%rename</tt>.
</p>
<p>
The 'equivalent' attribute is used in the implementation for the <a href="Library.html#Library_std_shared_ptr">shared_ptr smart pointer</a> library.
</p>
<H2><a name="Typemaps_nn48">11.14 More about %apply and %clear</a></H2>

View file

@ -529,8 +529,11 @@ like this:
SWIG_fail;
}
pystr = PyUnicode_AsUTF8String(pyobj);
if (!pystr) {
SWIG_fail;
}
str = strdup(PyBytes_AsString(pystr));
Py_XDECREF(pystr);
Py_DECREF(pystr);
%#else
if (!PyString_Check(pyobj)) {
PyErr_SetString(PyExc_ValueError, "Expected a string");

View file

@ -334,8 +334,8 @@ else
SWIGOPTPY3 = -py3
endif
PEP8 = @PEP8@
PEP8_FLAGS = --ignore=E402,E501,E30,W291,W391
PYCODESTYLE = @PYCODESTYLE@
PYCODESTYLE_FLAGS = --ignore=E402,E501,E30,W291,W391
# ----------------------------------------------------------------
# Build a C dynamically loadable module
@ -386,11 +386,11 @@ else
PYSCRIPT = $(RUNME)3.py
endif
PY2TO3 = 2to3 `2to3 -l | grep -v -E "Available|import$$" | awk '{print "-f "$$0}'`
PY2TO3 = @PY2TO3@ `@PY2TO3@ -l | grep -v -E "Available|import$$" | awk '{print "-f "$$0}'`
python_run: $(PYSCRIPT)
ifneq (,$(PEP8))
$(COMPILETOOL) $(PEP8) $(PEP8_FLAGS) $(PYSCRIPT)
ifneq (,$(PYCODESTYLE))
$(COMPILETOOL) $(PYCODESTYLE) $(PYCODESTYLE_FLAGS) $(PYSCRIPT)
endif
env PYTHONPATH=$$PWD $(RUNTOOL) $(PYTHON) $(PYSCRIPT) $(RUNPIPE)

View file

@ -6,7 +6,6 @@ constants2
extend
funcptr
import
java
multimap
multiple_inheritance
pointer

View file

@ -1,29 +0,0 @@
public class Example {
public int mPublicInt;
public Example() {
mPublicInt = 0;
}
public Example(int IntVal) {
mPublicInt = IntVal;
}
public int Add(int a, int b) {
return (a+b);
}
public float Add(float a, float b) {
return (a+b);
}
public String Add(String a, String b) {
return (a+b);
}
public Example Add(Example a, Example b) {
return new Example(a.mPublicInt + b.mPublicInt);
}
}

View file

@ -1,24 +0,0 @@
TOP = ../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
CXXSRCS =
TARGET = example
INTERFACE = example.i
LIBS = -lm
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' perl5_run
build: Example.class Example.h
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
CXXSHARED="gcj -fpic -shared Example.class" PERL5_CCFLAGS='' PERL5_EXP='' LIBS="-lstdc++" perl5_cpp
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' perl5_clean
rm -f *.class Example.h
Example.class Example.h: $(SRCDIR)Example.java
gcj -d . -fPIC -C -c -g $(SRCDIR)Example.java
gcjh Example.class

View file

@ -1,10 +0,0 @@
%module example
%include <cni.i>
%{
#include "Example.h"
%}
%include Example.h

View file

@ -1,29 +0,0 @@
use example;
example::JvCreateJavaVM(undef);
example::JvAttachCurrentThread(undef, undef);
$e1 = new example::Example(1);
print $e1->{mPublicInt},"\n";
$e2 = new example::Example(2);
print $e2->{mPublicInt},"\n";
$i = $e1->Add(1,2);
print $i,"\n";
$d = $e2->Add(1.0,2.0);
print $d,"\n";
$d = $e2->Add("1","2");
print $d,"\n";
$e3 = $e1->Add($e1,$e2);
print $e3->{mPublicInt},"\n";
$s = $e2->Add("a","b");
print $s,"\n";
example::JvDetachCurrentThread()

View file

@ -14,7 +14,6 @@ functor
import
import_template
import_packages
java
#libffi
multimap
operator

View file

@ -12,7 +12,7 @@ import_packages_subdirs = \
relativeimport2 \
relativeimport3 \
split_modules \
namespace_pkg
namespace_pkg \
check: build
@ -21,19 +21,19 @@ check: build
mkdir -p `dirname $$file`; \
cp "${SRCDIR}$$file" "$$file" || exit 1; \
done; \
fi; \
fi
for s in $(import_packages_subdirs); do \
(cd $$s && $(MAKE) check); \
(cd $$s && $(MAKE) check) || exit 1; \
done
build:
for s in $(import_packages_subdirs); do \
(cd $$s && $(MAKE) SWIGOPT='$(SWIGOPT)' LIBS='$(LIBS)' build); \
(cd $$s && $(MAKE) SWIGOPT='$(SWIGOPT)' LIBS='$(LIBS)' build) || exit 1; \
done
static:
for s in $(import_packages_subdirs); do \
(cd $$s && $(MAKE) SWIGOPT='$(SWIGOPT)' LIBS='$(LIBS)' static); \
(cd $$s && $(MAKE) SWIGOPT='$(SWIGOPT)' LIBS='$(LIBS)' static) || exit 1; \
done
clean:
@ -42,7 +42,7 @@ clean:
for file in `cd $(SRCDIR) && find . -type f -name "*.py"`; do \
rm -f "$$file" || exit 1; \
done; \
fi; \
fi
for s in $(import_packages_subdirs); do \
(cd $$s && $(MAKE) clean); \
(cd $$s && $(MAKE) clean) || exit 1; \
done

View file

@ -5,6 +5,10 @@ import os.path
testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
print "Testing " + testname + " - %module(package=...) + python 'import' in __init__.py"
if sys.version_info < (2, 5):
print " Skipping test as Python version is < 2.5 and does not support relative import syntax: 'from . import x'"
sys.exit(0)
if sys.version_info < (3, 0):
import py2.pkg2
print " Finished importing py2.pkg2"

View file

@ -5,6 +5,10 @@ import os.path
testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
print "Testing " + testname + " - %module(package=...) + python 'import' in __init__.py"
if sys.version_info < (2, 5):
print " Skipping test as Python version is < 2.5 and does not support relative import syntax: 'from . import x'"
sys.exit(0)
if sys.version_info < (3, 0):
import py2.pkg2
print " Finished importing py2.pkg2"

View file

@ -5,6 +5,10 @@ import os.path
testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
print "Testing " + testname + " - %module(package=...) + python 'import' in __init__.py"
if sys.version_info < (2, 5):
print " Skipping test as Python version is < 2.5 and does not support relative import syntax: 'from . import x'"
sys.exit(0)
if sys.version_info < (3, 0):
import py2.pkg2
print " Finished importing py2.pkg2"

View file

@ -5,6 +5,10 @@ import os.path
testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
print "Testing " + testname + " - %module(package=...) with -relativeimport"
if sys.version_info < (2, 5):
print " Skipping test as Python version is < 2.5 and does not support relative import syntax: 'from . import x'"
sys.exit(0)
if sys.version_info < (3, 0):
import py2.pkg2.bar
print " Finished importing py2.pkg2.bar"

View file

@ -5,6 +5,10 @@ import os.path
testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
print "Testing " + testname + " - %module(package=...) + python 'import' in __init__.py"
if sys.version_info < (2, 5):
print " Skipping test as Python version is < 2.5 and does not support relative import syntax: 'from . import x'"
sys.exit(0)
if sys.version_info < (3, 0):
import py2.pkg2.bar
print " Finished importing py2.pkg2.bar"

View file

@ -5,6 +5,10 @@ import os.path
testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
print "Testing " + testname + " - %module(package=...) with -relativeimport"
if sys.version_info < (2, 5):
print " Skipping test as Python version is < 2.5 and does not support relative import syntax: 'from . import x'"
sys.exit(0)
if sys.version_info < (3, 0):
import py2.pkg2.bar
print " Finished importing py2.pkg2.bar"

View file

@ -6,21 +6,21 @@ subdirs = vanilla vanilla_split
check: build
for s in $(subdirs); do \
(cd $$s && $(MAKE) check); \
(cd $$s && $(MAKE) check) || exit 1; \
done
build:
for s in $(subdirs); do \
(cd $$s && $(MAKE) SWIGOPT='$(SWIGOPT)' LIBS='$(LIBS)' build); \
(cd $$s && $(MAKE) SWIGOPT='$(SWIGOPT)' LIBS='$(LIBS)' build) || exit 1; \
done
static:
for s in $(subdirs); do \
(cd $$s && $(MAKE) SWIGOPT='$(SWIGOPT)' LIBS='$(LIBS)' static); \
(cd $$s && $(MAKE) SWIGOPT='$(SWIGOPT)' LIBS='$(LIBS)' static) || exit 1; \
done
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' python_clean
for s in $(subdirs); do \
(cd $$s && $(MAKE) clean); \
(cd $$s && $(MAKE) clean) || exit 1; \
done

View file

@ -19,4 +19,6 @@ static:
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' TARGET='foo' python_clean
cd pkg1 && $(MAKE) -f $(TOP)/../Makefile SRCDIR='$(SRCDIR)' TARGET='foo' python_clean
if test -d pkg1; then \
cd pkg1 && $(MAKE) -f $(TOP)/../Makefile SRCDIR='$(SRCDIR)' TARGET='foo' python_clean; \
fi

View file

@ -1,29 +0,0 @@
public class Example {
public int mPublicInt;
public Example() {
mPublicInt = 0;
}
public Example(int IntVal) {
mPublicInt = IntVal;
}
public int Add(int a, int b) {
return (a+b);
}
public float Add(float a, float b) {
return (a+b);
}
public String Add(String a, String b) {
return (a+b);
}
public Example Add(Example a, Example b) {
return new Example(a.mPublicInt + b.mPublicInt);
}
}

View file

@ -1,25 +0,0 @@
TOP = ../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
CXXSRCS =
TARGET = example
INTERFACE = example.i
LIBS = -lm
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' python_run
build: Example.class Example.h
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
CXXSHARED="gcj -fpic -shared Example.class" DEFS='' LIBS="-lstdc++" python_cpp
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' python_clean
rm -f $(TARGET).py
rm -f *.class Example.h
Example.class Example.h: $(SRCDIR)Example.java
gcj -d . -fPIC -C -c -g $(SRCDIR)Example.java
gcjh Example.class

View file

@ -1,13 +0,0 @@
%module example
%include <cni.i>
%{
#include "Example.h"
%}
%include Example.h
%extend Example {
~Example() {}
}

View file

@ -1,16 +0,0 @@
from example import *
JvCreateJavaVM(None)
JvAttachCurrentThread(None, None)
e1 = Example(1)
e2 = Example(2)
print e1.Add(1, 2)
print e1.Add(1.0, 2.0)
e3 = e1.Add(e1, e2)
print e3.mPublicInt
print e1.Add("1", "2")
JvDetachCurrentThread()

View file

@ -39,7 +39,11 @@ extern int gcd(int x, int y);
%#if PY_VERSION_HEX >= 0x03000000
{
PyObject *utf8str = PyUnicode_AsUTF8String(s);
const char *cstr = PyBytes_AsString(utf8str);
const char *cstr;
if (!utf8str) {
SWIG_fail;
}
cstr = PyBytes_AsString(utf8str);
$2[i] = strdup(cstr);
Py_DECREF(utf8str);
}
@ -72,6 +76,9 @@ extern int gcdmain(int argc, char *argv[]);
SWIG_fail;
}
utf8str = PyUnicode_AsUTF8String($input);
if (!utf8str) {
SWIG_fail;
}
PyBytes_AsStringAndSize(utf8str, &cstr, &len);
$1 = strncpy((char *)malloc(len+1), cstr, (size_t)len);
$2 = (int)len;
@ -105,6 +112,9 @@ extern int count(char *bytes, int len, char c);
char *cstr;
Py_ssize_t len;
PyObject *utf8str = PyUnicode_AsUTF8String($input);
if (!utf8str) {
SWIG_fail;
}
PyBytes_AsStringAndSize(utf8str, &cstr, &len);
$1 = strncpy((char *)malloc(len+1), cstr, (size_t)len);
$2 = (int)len;

View file

@ -52,14 +52,14 @@ print " Tring to set 'path'"
try:
example.cvar.path = "Whoa!"
print "Hey, what's going on?!?! This shouldn't work"
except:
except Exception:
print "Good."
print " Trying to set 'status'"
try:
example.cvar.status = 0
print "Hey, what's going on?!?! This shouldn't work"
except:
except Exception:
print "Good."

View file

@ -9,7 +9,6 @@ functor
hashargs
import
import_template
java
mark_function
multimap
operator

View file

@ -39,7 +39,11 @@ GC.start
# C++ object
ok = false
begin
puts tiger2.get_name
# Let's stress the GC a bit, a single pass might not be enough.
10.times {
GC.start
puts tiger2.get_name
}
rescue ObjectPreviouslyDeleted => error
ok = true
end

View file

@ -1,29 +0,0 @@
public class Example {
public int mPublicInt;
public Example() {
mPublicInt = 0;
}
public Example(int IntVal) {
mPublicInt = IntVal;
}
public int Add(int a, int b) {
return (a+b);
}
public float Add(float a, float b) {
return (a+b);
}
public String Add(String a, String b) {
return (a+b);
}
public Example Add(Example a, Example b) {
return new Example(a.mPublicInt + b.mPublicInt);
}
}

View file

@ -1,24 +0,0 @@
TOP = ../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
CXXSRCS =
TARGET = example
INTERFACE = example.i
LIBS = -lm
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' ruby_run
build: Example.class Example.h
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
CXXSHARED="gcj -fpic -shared Example.class" LIBS="-lstdc++" DEFS='' ruby_cpp
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' ruby_clean
rm -f *.class Example.h
Example.class Example.h: $(SRCDIR)Example.java
gcj -d . -fPIC -C -c -g $(SRCDIR)Example.java
gcjh Example.class

View file

@ -1,9 +0,0 @@
%module example
%include <cni.i>
%{
#include "Example.h"
%}
%include Example.h

View file

@ -1,18 +0,0 @@
require 'example'
Example.JvCreateJavaVM(nil)
Example.JvAttachCurrentThread(nil, nil)
e1 = Example::Example.new(1)
e2 = Example::Example.new(2)
print e1.Add(1,2),"\n"
print e1.Add(1.0,2.0),"\n"
e3 = e1.Add(e1,e2)
print e3.mPublicInt,"\n"
print e1.Add("1","2"),"\n"
Example.JvDetachCurrentThread()

View file

@ -5,7 +5,6 @@ contract
enum
funcptr
import
java
multimap
operator
pointer

View file

@ -1,29 +0,0 @@
public class Example {
public int mPublicInt;
public Example() {
mPublicInt = 0;
}
public Example(int IntVal) {
mPublicInt = IntVal;
}
public int Add(int a, int b) {
return (a+b);
}
public float Add(float a, float b) {
return (a+b);
}
public String Add(String a, String b) {
return (a+b);
}
public Example Add(Example a, Example b) {
return new Example(a.mPublicInt + b.mPublicInt);
}
}

View file

@ -1,24 +0,0 @@
TOP = ../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
CXXSRCS =
TARGET = example
INTERFACE = example.i
LIBS = -lm
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' tcl_run
build: Example.class Example.h
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
TCLCXXSHARED="gcj -fpic -shared Example.class " LIBS="-lstdc++" DEFS='' tcl_cpp
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' tcl_clean
rm -f *.class Example.h
Example.class Example.h: $(SRCDIR)Example.java
gcj -d . -fPIC -C -c -g $(SRCDIR)Example.java
gcjh Example.class

View file

@ -1,8 +0,0 @@
%module example
%include <cni.i>
%{
#include "Example.h"
%}
%include Example.h

View file

@ -1,15 +0,0 @@
catch { load ./example[info sharedlibextension] example}
JvCreateJavaVM NULL
JvAttachCurrentThread NULL NULL
Example e1 1
Example e2 2
puts "[e1 cget -mPublicInt]"
puts "[e2 cget -mPublicInt]"
puts "[e2 Add 1 2]"
puts "[e2 Add 1.0 2.0]"
puts "[e2 Add '1' '2']"
JvDetachCurrentThread

View file

@ -3,7 +3,7 @@
%module class_scope_namespace
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) H::HH;
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Space8::I::II;
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Space8::I_::II;
%inline %{
struct A;
@ -107,12 +107,12 @@ void hhh(H::HH) {}
namespace Space8 {
struct II;
struct I {
struct I_ {
struct II {
void ii(Space8::I::II, I::II) {}
void ii(Space8::I_::II, I_::II) {}
};
};
void iii(Space8::I::II, I::II) {}
void iii(Space8::I_::II, I_::II) {}
}
struct J;

View file

@ -89,7 +89,6 @@ CPP_TEST_BROKEN += \
extend_variable \
li_boost_shared_ptr_template \
nested_private \
overload_complicated \
rename_camel \
template_default_pointer \
template_private_assignment \
@ -165,6 +164,7 @@ CPP_TEST_CASES += \
cpp_typedef \
curiously_recurring_template_pattern \
default_args \
default_arg_expressions \
default_arg_values \
default_constructor \
defvalue_constructor \
@ -182,6 +182,7 @@ CPP_TEST_CASES += \
director_detect \
director_enum \
director_exception \
director_exception_catches \
director_extend \
director_finalizer \
director_frob \
@ -193,6 +194,7 @@ CPP_TEST_CASES += \
director_nspace_director_name_collision \
director_overload \
director_overload2 \
director_ownership \
director_pass_by_value \
director_primitives \
director_property \
@ -264,9 +266,10 @@ CPP_TEST_CASES += \
li_attribute \
li_attribute_template \
li_boost_shared_ptr \
li_boost_shared_ptr_bits \
li_boost_shared_ptr_template \
li_boost_shared_ptr_attribute \
li_boost_shared_ptr_bits \
li_boost_shared_ptr_director \
li_boost_shared_ptr_template \
li_carrays_cpp \
li_cdata_cpp \
li_cpointer_cpp \
@ -317,6 +320,7 @@ CPP_TEST_CASES += \
nested_template_base \
nested_workaround \
newobject1 \
newobject3 \
null_pointer \
operator_overload \
operator_overload_break \
@ -325,6 +329,7 @@ CPP_TEST_CASES += \
ordering \
overload_arrays \
overload_bool \
overload_complicated \
overload_copy \
overload_extend \
overload_method \
@ -405,6 +410,7 @@ CPP_TEST_CASES += \
template_basic \
template_base_template \
template_classes \
template_class_reuse_name \
template_const_ref \
template_construct \
template_templated_constructors \
@ -486,6 +492,7 @@ CPP_TEST_CASES += \
throw_exception \
typedef_array_member \
typedef_class \
typedef_classforward_same_name \
typedef_funcptr \
typedef_inherit \
typedef_mptr \
@ -506,6 +513,7 @@ CPP_TEST_CASES += \
typemap_numinputs \
typemap_template \
typemap_template_parm_typedef \
typemap_template_typedef \
typemap_out_optimal \
typemap_qualifier_strip \
typemap_variables \
@ -534,6 +542,7 @@ CPP_TEST_CASES += \
varargs_overload \
variable_replacement \
virtual_destructor \
virtual_derivation \
virtual_poly \
virtual_vs_nonvirtual_base \
voidtest \
@ -650,6 +659,7 @@ C_TEST_CASES += \
char_constant \
const_const \
constant_expr \
default_args_c \
empty_c \
enums \
enum_forward \
@ -692,6 +702,7 @@ C_TEST_CASES += \
string_simple \
struct_rename \
struct_initialization \
typedef_classforward_same_name \
typedef_struct \
typemap_subst \
union_parameter \

View file

@ -14,31 +14,53 @@
%template(VectorStdCplx) std::vector<std::complex<double> >;
#endif
%inline
%inline
{
std::complex<double> Conj(const std::complex<double>& a)
std::complex<double> Conj(std::complex<double> a)
{
return std::conj(a);
}
}
std::complex<float> Conjf(const std::complex<float>& a)
std::complex<float> Conjf(std::complex<float> a)
{
return std::conj(a);
}
}
#if 1
std::vector<std::complex<double> > Copy_h(const std::vector<std::complex<double> >& a)
std::vector<std::complex<double> > CopyHalf(std::vector<std::complex<double> > a)
{
std::vector<std::complex<double> > b(a.size()/2);
std::copy(a.begin(), a.begin()+a.size()/2, b.begin());
return b;
}
#endif
}
using namespace std;
struct ComplexPair
{
std::complex<double> z1, z2;
std::complex<double> z1;
complex<double> z2;
};
const complex<double>& Conj2(const complex<double>& a)
{
static complex<double> ret;
ret = std::conj(a);
return ret;
}
const complex<float>& Conjf2(const complex<float>& a)
{
static complex<float> ret;
ret = std::conj(a);
return ret;
}
const vector<complex<double> >& CopyHalfRef(const vector<complex<double> >& a)
{
static vector<complex<double> > b;
b = CopyHalf(a);
return b;
}
}
@ -48,7 +70,7 @@
%{
%}
%inline
%inline
{
complex Conj(complex a)
{

View file

@ -1,20 +1,16 @@
%module(directors="1") cpp11_directors
%feature("director");
%{
%inline %{
class Foo {
public:
virtual ~Foo() noexcept {}
virtual int ping() noexcept = 0;
virtual int pong() noexcept = 0;
virtual int pang() const& noexcept = 0;
virtual int peng() & noexcept = 0;
virtual int pung() & = 0;
};
%}
class Foo {
public:
virtual ~Foo() noexcept {}
virtual int ping() noexcept = 0;
virtual int pong() noexcept = 0;
};

View file

@ -6,6 +6,16 @@
%warnfilter(SWIGWARN_PARSE_KEYWORD) final; // 'final' is a java keyword, renaming to '_final'
%warnfilter(SWIGWARN_PARSE_KEYWORD) override; // 'override' is a C# keyword, renaming to '_override'
%{
#if defined(_MSC_VER)
#pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
#endif
#if __GNUC__ >= 7
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated" // dynamic exception specifications are deprecated in C++11
#endif
%}
%inline %{
struct Base {
@ -131,3 +141,12 @@ void DerivedNoVirtualStruct::cd() {}
void DerivedNoVirtualStruct::ef() {}
DerivedNoVirtualStruct::~DerivedNoVirtualStruct() {}
%}
%{
#if defined(_MSC_VER)
#pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
#endif
#if __GNUC__ >= 7
#pragma GCC diagnostic pop
#endif
%}

View file

@ -26,6 +26,16 @@
%warnfilter(SWIGWARN_CPP11_LAMBDA) Space1::lambda19;
%warnfilter(SWIGWARN_CPP11_LAMBDA) Space1::Space2::lambda20;
%{
#if defined(_MSC_VER)
#pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
#endif
#if __GNUC__ >= 7
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated" // dynamic exception specifications are deprecated in C++11
#endif
%}
%inline %{
/* Defined lambda function with return value. */
auto lambda1 = [](int x, int y) -> int { return x+y; };
@ -105,3 +115,11 @@ int lambda102 = [] (int a, int b) mutable { return a + b; }(1, 2);
void lambda_init(int = ([=]{ return 0; })());
%}
%{
#if defined(_MSC_VER)
#pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
#endif
#if __GNUC__ >= 7
#pragma GCC diagnostic pop
#endif
%}

View file

@ -7,10 +7,10 @@
class Foo
{
int m;
public:
Foo(int i) : m(i) {}
int get_m() { return m;}
int m;
};
std::shared_ptr<Foo> foo(Foo v) {
@ -45,10 +45,10 @@ std::vector<std::shared_ptr<const Foo> > const_foo_vec(Foo v) {
class Foo
{
int m;
public:
Foo(int i);
int get_m();
int m;
};
std::shared_ptr<Foo> foo(Foo v);
std::shared_ptr<const Foo> const_foo(Foo v);

View file

@ -15,11 +15,11 @@ class C;
%inline %{
class C {
int m;
public:
C() : m(-1) {}
C(int i) : m(i) {}
int get_m() { return m; }
int m;
};
%}

View file

@ -0,0 +1,89 @@
%module cpp11_shared_ptr_overload
// Tests to ensure valid overloading in C++ between shared_ptr and other types result in code that compiles
// and all but the 1st overloaded method are automatically ignored/shadowed.
// Tests the 'equivalent' attribute in the 'typecheck' typemap.
%include <std_string.i>
%include <std_shared_ptr.i>
%warnfilter(SWIGWARN_LANG_OVERLOAD_IGNORED,SWIGWARN_LANG_OVERLOAD_SHADOW) UseA(std::shared_ptr<MyType> mytype);
%warnfilter(SWIGWARN_LANG_OVERLOAD_IGNORED,SWIGWARN_LANG_OVERLOAD_SHADOW) UseB(int, std::shared_ptr<MyType> mytype);
%warnfilter(SWIGWARN_LANG_OVERLOAD_IGNORED,SWIGWARN_LANG_OVERLOAD_SHADOW) UseC(int, std::shared_ptr<MyType> mytype, std::shared_ptr<MyType>);
%warnfilter(SWIGWARN_LANG_OVERLOAD_IGNORED,SWIGWARN_LANG_OVERLOAD_SHADOW) UseX(MyType &mytype);
%warnfilter(SWIGWARN_LANG_OVERLOAD_IGNORED,SWIGWARN_LANG_OVERLOAD_SHADOW) UseY(int, MyType &mytype);
%warnfilter(SWIGWARN_LANG_OVERLOAD_IGNORED,SWIGWARN_LANG_OVERLOAD_SHADOW) UseZ(int, MyType &mytype, std::shared_ptr<MyType>);
%warnfilter(SWIGWARN_LANG_OVERLOAD_IGNORED,SWIGWARN_LANG_OVERLOAD_SHADOW) Combo1;
%warnfilter(SWIGWARN_LANG_OVERLOAD_IGNORED,SWIGWARN_LANG_OVERLOAD_SHADOW) Combo2;
%warnfilter(SWIGWARN_LANG_OVERLOAD_IGNORED,SWIGWARN_LANG_OVERLOAD_SHADOW) Combo3;
%warnfilter(SWIGWARN_LANG_OVERLOAD_IGNORED,SWIGWARN_LANG_OVERLOAD_SHADOW) Combo4;
%warnfilter(SWIGWARN_LANG_OVERLOAD_IGNORED,SWIGWARN_LANG_OVERLOAD_SHADOW) Combo5;
%warnfilter(SWIGWARN_LANG_OVERLOAD_IGNORED,SWIGWARN_LANG_OVERLOAD_SHADOW) Combo6;
%warnfilter(SWIGWARN_LANG_OVERLOAD_IGNORED,SWIGWARN_LANG_OVERLOAD_SHADOW) Combo7;
%shared_ptr(MyType);
%inline %{
#include <memory>
#include <string>
struct MyType {
std::string val;
MyType(std::string val = std::string()) : val(val) {}
};
// ref
std::string UseA(MyType &mytype) { return mytype.val + " ref"; }
std::string UseA(std::shared_ptr<MyType> mytype) { return mytype->val + " sharedptr"; }
std::string UseB(int, MyType &mytype) { return mytype.val + " ref"; }
std::string UseB(int, std::shared_ptr<MyType> mytype) { return mytype->val + " sharedptr"; }
std::string UseC(int, MyType &mytype, std::shared_ptr<MyType>) { return mytype.val + " ref"; }
std::string UseC(int, std::shared_ptr<MyType> mytype, std::shared_ptr<MyType>) { return mytype->val + " sharedptr"; }
// sharedptr
std::string UseX(std::shared_ptr<MyType> mytype) { return mytype->val + " sharedptr"; }
std::string UseX(MyType &mytype) { return mytype.val + " ref"; }
std::string UseY(int, std::shared_ptr<MyType> mytype) { return mytype->val + " sharedptr"; }
std::string UseY(int, MyType &mytype) { return mytype.val + " ref"; }
std::string UseZ(int, std::shared_ptr<MyType> mytype, std::shared_ptr<MyType>) { return mytype->val + " sharedptr"; }
std::string UseZ(int, MyType &mytype, std::shared_ptr<MyType>) { return mytype.val + " ref"; }
// Combo1-4
std::string Combo1(MyType mytype) { return mytype.val + "Combo1"; }
std::string Combo1(MyType *mytype) { return ""; }
std::string Combo1(std::shared_ptr<MyType> mytype) { return ""; }
std::string Combo1(std::shared_ptr<MyType>* mytype) { return ""; }
std::string Combo2(MyType *mytype) { return mytype->val + "Combo2"; }
std::string Combo2(std::shared_ptr<MyType> mytype) { return ""; }
std::string Combo2(std::shared_ptr<MyType>* mytype) { return ""; }
std::string Combo2(MyType mytype) { return ""; }
std::string Combo3(std::shared_ptr<MyType> mytype) { return mytype->val + "Combo3"; }
std::string Combo3(std::shared_ptr<MyType>* mytype) { return ""; }
std::string Combo3(MyType mytype) { return ""; }
std::string Combo3(MyType *mytype) { return ""; }
std::string Combo4(std::shared_ptr<MyType>* mytype) { return (*mytype)->val + "Combo4"; }
std::string Combo4(MyType mytype) { return ""; }
std::string Combo4(MyType *mytype) { return ""; }
std::string Combo4(std::shared_ptr<MyType> mytype) { return ""; }
// Combo5-7
std::string Combo5(MyType &mytype) { return mytype.val + "Combo5"; }
std::string Combo5(MyType *mytype) { return ""; }
std::string Combo5(std::shared_ptr<MyType> mytype) { return ""; }
std::string Combo6(MyType *mytype) { return mytype->val + "Combo6"; }
std::string Combo6(std::shared_ptr<MyType> mytype) { return ""; }
std::string Combo6(MyType &mytype) { return ""; }
std::string Combo7(std::shared_ptr<MyType> mytype) { return mytype->val + "Combo7"; }
std::string Combo7(MyType &mytype) { return ""; }
std::string Combo7(MyType *mytype) { return ""; }
%}

View file

@ -16,19 +16,19 @@
%{
class Base {
int m;
public:
Base() : m(-1) {}
Base(int i) : m(i) {}
int get_m() { return m; }
int m;
};
class Derived : public Base {
int n;
public:
Derived() : n(-2) {}
Derived(int i) : n(i) {}
int get_n() { return n; }
int n;
};
typedef std::shared_ptr<Base> BasePtr;
@ -96,18 +96,18 @@ int base_num(std::map<int, BasePtr > v) {
%template(DerivedMap) std::map<int, std::shared_ptr<Derived> >;
class Base {
int m;
public:
Base();
int get_m();
int m;
};
class Derived : public Base {
int n;
public:
Derived();
Derived(int i);
int get_n();
int n;
};
typedef std::shared_ptr<Base> BasePtr;
@ -135,20 +135,20 @@ int base_num(std::map<int, BasePtr > v);
%inline %{
class Base2 {
int m;
public:
Base2() : m(-1) {}
Base2(int i) : m(i) {}
int get_m() { return m; }
int m;
};
class Derived2 : public Base2 {
int n;
public:
Derived2() : n(0) {}
Derived2(int i) : n(i) {}
int get_n_2() { return n; }
int n;
};
%}

View file

@ -29,6 +29,10 @@ CPP_TEST_CASES = \
li_boost_intrusive_ptr
CPP11_TEST_CASES = \
cpp11_shared_ptr_const \
cpp11_shared_ptr_nullptr_in_containers \
cpp11_shared_ptr_overload \
cpp11_shared_ptr_upcast \
cpp11_strongly_typed_enumerations_simple \
include $(srcdir)/../common.mk

View file

@ -16,14 +16,23 @@ public class complextest_runme {
if ( complextest.Conjf(a) != Complex.Conjugate(a) )
throw new Exception("std::complex<float> test failed");
if ( complextest.Conj2(a) != Complex.Conjugate(a) )
throw new Exception("std::complex<double> test failed");
if ( complextest.Conjf2(a) != Complex.Conjugate(a) )
throw new Exception("std::complex<float> test failed");
var vec = new VectorStdCplx();
vec.Add(new Complex(1, 2));
vec.Add(new Complex(2, 3));
vec.Add(new Complex(4, 3));
vec.Add(new Complex(1, 0));
if ( complextest.Copy_h(vec).Count != 2 )
throw new Exception("vector<complex> test failed");
if ( complextest.CopyHalf(vec).Count != 2 )
throw new Exception("CopyHalf test failed");
if ( complextest.CopyHalfRef(vec).Count != 2 )
throw new Exception("CopyHalfRef test failed");
var p = new ComplexPair();
p.z1 = new Complex(0, 1);

View file

@ -16,6 +16,7 @@ Expected output if PrintDebug enabled:
Base - Val(444.555)
Base - Ref(444.555)
Base - Ptr(444.555)
Base - ConstPtrRef(444.555)
Base - FullyOverloaded(int 10)
Base - FullyOverloaded(bool 1)
Base - SemiOverloaded(int -678)
@ -26,6 +27,7 @@ Base - DefaultParms(10, 1.1)
Derived - Val(444.555)
Derived - Ref(444.555)
Derived - Ptr(444.555)
Derived - ConstPtrRef(444.555)
Derived - FullyOverloaded(int 10)
Derived - FullyOverloaded(bool 1)
Derived - SemiOverloaded(int -678)
@ -36,6 +38,7 @@ Derived - DefaultParms(10, 1.1)
CSharpDerived - Val(444.555)
CSharpDerived - Ref(444.555)
CSharpDerived - Ptr(444.555)
CSharpDerived - ConstPtrRef(444.555)
CSharpDerived - FullyOverloaded(int 10)
CSharpDerived - FullyOverloaded(bool True)
CSharpDerived - SemiOverloaded(-678)
@ -59,7 +62,7 @@ public class runme
void run()
{
if (director_classes.PrintDebug) Console.WriteLine("------------ Start ------------ ");
if (director_classes.PrintDebug) Console.WriteLine("------------ Start ------------");
Caller myCaller = new Caller();
@ -85,7 +88,7 @@ public class runme
makeCalls(myCaller, myBase);
}
if (director_classes.PrintDebug) Console.WriteLine("------------ Finish ------------ ");
if (director_classes.PrintDebug) Console.WriteLine("------------ Finish ------------");
}
void makeCalls(Caller myCaller, Base myBase)
@ -99,6 +102,7 @@ public class runme
if (myCaller.ValCall(dh).val != dh.val) throw new Exception("failed");
if (myCaller.RefCall(dh).val != dh.val) throw new Exception("failed");
if (myCaller.PtrCall(dh).val != dh.val) throw new Exception("failed");
if (myCaller.ConstPtrRefCall(dh).val != dh.val) throw new Exception("failed");
// Fully overloaded method test (all methods in base class are overloaded)
if (NAMESPACE + myCaller.FullyOverloadedCall(10) != myBase.GetType() + "::FullyOverloaded(int)") throw new Exception("failed");
@ -142,6 +146,11 @@ public class CSharpDerived : Base
if (director_classes.PrintDebug) Console.WriteLine("CSharpDerived - Ptr({0})", x.val);
return x;
}
public override DoubleHolder ConstPtrRef(DoubleHolder x)
{
if (director_classes.PrintDebug) Console.WriteLine("CSharpDerived - ConstPtrRef({0})", x.val);
return x;
}
public override String FullyOverloaded(int x)
{
if (director_classes.PrintDebug) Console.WriteLine("CSharpDerived - FullyOverloaded(int {0})", x);

View file

@ -0,0 +1,111 @@
using System;
using li_boost_shared_ptr_directorNamespace;
public class li_boost_shared_ptr_director_runme {
private static void check(int got, int expected) {
if (got != expected)
throw new Exception("Failed, got: " + got + " expected: " + expected);
}
public static void Main() {
Derived a = new Derived(false);
Derived b = new Derived(true);
check(li_boost_shared_ptr_director.call_ret_c_shared_ptr(a), 1);
check(li_boost_shared_ptr_director.call_ret_c_shared_ptr(b), -1);
check(li_boost_shared_ptr_director.call_ret_c_by_value(a), 1);
check(li_boost_shared_ptr_director.call_ret_c_shared_ptr(a), 1);
check(li_boost_shared_ptr_director.call_ret_c_shared_ptr(b), -1);
check(li_boost_shared_ptr_director.call_ret_c_by_value(a), 1);
check(li_boost_shared_ptr_director.call_take_c_by_value(a), 5);
check(li_boost_shared_ptr_director.call_take_c_by_ref(a), 6);
check(li_boost_shared_ptr_director.call_take_c_by_pointer(a), 7);
check(li_boost_shared_ptr_director.call_take_c_by_pointer_ref(a), 8);
check(li_boost_shared_ptr_director.call_take_c_shared_ptr_by_value(a), 9);
check(li_boost_shared_ptr_director.call_take_c_shared_ptr_by_ref(a), 10);
check(li_boost_shared_ptr_director.call_take_c_shared_ptr_by_pointer(a), 11);
check(li_boost_shared_ptr_director.call_take_c_shared_ptr_by_pointer_ref(a), 12);
check(li_boost_shared_ptr_director.call_take_c_by_pointer_with_null(a), -2);
check(li_boost_shared_ptr_director.call_take_c_by_pointer_ref_with_null(a), -3);
check(li_boost_shared_ptr_director.call_take_c_shared_ptr_by_value_with_null(a), -4);
check(li_boost_shared_ptr_director.call_take_c_shared_ptr_by_ref_with_null(a), -5);
check(li_boost_shared_ptr_director.call_take_c_shared_ptr_by_pointer_with_null(a), -6);
check(li_boost_shared_ptr_director.call_take_c_shared_ptr_by_pointer_ref_with_null(a), -7);
}
}
class Derived : Base {
private bool return_none;
public Derived(bool flag) : base() {
this.return_none = flag;
}
public override C ret_c_shared_ptr() {
if (this.return_none)
return null;
else
return new C();
}
public override C ret_c_by_value() {
return new C();
}
public override int take_c_by_value(C c) {
return c.get_m();
}
public override int take_c_by_ref(C c) {
return c.get_m();
}
public override int take_c_by_pointer(C c) {
if (c != null)
return c.get_m();
else
return -2;
}
public override int take_c_by_pointer_ref(C c) {
if (c != null)
return c.get_m();
else
return -3;
}
public override int take_c_shared_ptr_by_value(C c) {
if (c != null)
return c.get_m();
else
return -4;
}
public override int take_c_shared_ptr_by_ref(C c) {
if (c != null)
return c.get_m();
else
return -5;
}
public override int take_c_shared_ptr_by_pointer(C c) {
if (c != null)
return c.get_m();
else
return -6;
}
public override int take_c_shared_ptr_by_pointer_ref(C c) {
if (c != null)
return c.get_m();
else
return -7;
}
}

View file

@ -177,6 +177,17 @@ public class li_std_vector_runme {
if (doubleArray[i] != dvCopy[i])
throw new Exception("Copy constructor failed, index:" + i);
}
if (dvCopy.Count != doubleArray.Length)
throw new Exception("Copy constructor lengths mismatch");
// ToArray test
double[] dvArray = dv.ToArray();
for (int i=0; i<doubleArray.Length; i++) {
if (doubleArray[i] != dvArray[i])
throw new Exception("ToArray failed, index:" + i);
}
if (dvArray.Length != doubleArray.Length)
throw new Exception("ToArray lengths mismatch");
}
{
// Repeat() test

View file

@ -24,6 +24,12 @@ CPP_TEST_CASES = \
d_nativepointers \
exception_partial_info
CPP11_TEST_CASES = \
cpp11_shared_ptr_const \
cpp11_shared_ptr_nullptr_in_containers \
cpp11_shared_ptr_overload \
cpp11_shared_ptr_upcast \
include $(srcdir)/../common.mk
# Overridden variables here

View file

@ -18,6 +18,7 @@
* Base - Val(444.555)
* Base - Ref(444.555)
* Base - Ptr(444.555)
* Base - ConstPtrRef(444.555)
* Base - FullyOverloaded(int 10)
* Base - FullyOverloaded(bool 1)
* Base - SemiOverloaded(int -678)
@ -28,6 +29,7 @@
* Derived - Val(444.555)
* Derived - Ref(444.555)
* Derived - Ptr(444.555)
* Derived - ConstPtrRef(444.555)
* Derived - FullyOverloaded(int 10)
* Derived - FullyOverloaded(bool 1)
* Derived - SemiOverloaded(int -678)
@ -38,6 +40,7 @@
* DDerived - Val(444.555)
* DDerived - Ref(444.555)
* DDerived - Ptr(444.555)
* DDerived - ConstPtrRef(444.555)
* DDerived - FullyOverloaded(int 10)
* DDerived - FullyOverloaded(bool True)
* DDerived - SemiOverloaded(-678)
@ -57,7 +60,7 @@ import director_classes.Derived;
import director_classes.DoubleHolder;
void main() {
if (PrintDebug) Stdout.formatln("------------ Start ------------ ");
if (PrintDebug) Stdout.formatln("------------ Start ------------");
auto myCaller = new Caller();
@ -83,7 +86,7 @@ void main() {
makeCalls(myCaller, myBase);
}
if (PrintDebug) Stdout.formatln("------------ Finish ------------ ");
if (PrintDebug) Stdout.formatln("------------ Finish ------------");
}
void makeCalls(Caller myCaller, Base myBase) {
@ -96,6 +99,7 @@ void makeCalls(Caller myCaller, Base myBase) {
if (myCaller.ValCall(dh).val != dh.val) throw new Exception("[1] failed");
if (myCaller.RefCall(dh).val != dh.val) throw new Exception("[2] failed");
if (myCaller.PtrCall(dh).val != dh.val) throw new Exception("[3] failed");
if (myCaller.ConstPtrRefCall(dh).val != dh.val) throw new Exception("[3] failed");
// Fully overloaded method test (all methods in base class are overloaded)
if (myCaller.FullyOverloadedCall(10) != myBaseType ~ "::FullyOverloaded(int)") throw new Exception("[4] failed");
@ -136,6 +140,11 @@ public class DDerived : Base {
return x;
}
public override DoubleHolder ConstPtrRef(DoubleHolder x) {
if (PrintDebug) Stdout.formatln("DDerived - ConstPtrRef({0:d3})", x.val);
return x;
}
public override char[] FullyOverloaded(int x) {
if (PrintDebug) Stdout.formatln("DDerived - FullyOverloaded(int {0})", x);
return "DDerived::FullyOverloaded(int)";

View file

@ -18,6 +18,7 @@
* Base - Val(444.555)
* Base - Ref(444.555)
* Base - Ptr(444.555)
* Base - ConstPtrRef(444.555)
* Base - FullyOverloaded(int 10)
* Base - FullyOverloaded(bool 1)
* Base - SemiOverloaded(int -678)
@ -28,6 +29,7 @@
* Derived - Val(444.555)
* Derived - Ref(444.555)
* Derived - Ptr(444.555)
* Derived - ConstPtrRef(444.555)
* Derived - FullyOverloaded(int 10)
* Derived - FullyOverloaded(bool 1)
* Derived - SemiOverloaded(int -678)
@ -38,6 +40,7 @@
* DDerived - Val(444.555)
* DDerived - Ref(444.555)
* DDerived - Ptr(444.555)
* DDerived - ConstPtrRef(444.555)
* DDerived - FullyOverloaded(int 10)
* DDerived - FullyOverloaded(bool true)
* DDerived - SemiOverloaded(-678)
@ -58,7 +61,7 @@ import director_classes.Derived;
import director_classes.DoubleHolder;
void main() {
if (PrintDebug) writeln("------------ Start ------------ ");
if (PrintDebug) writeln("------------ Start ------------");
auto myCaller = new Caller();
@ -84,7 +87,7 @@ void main() {
makeCalls(myCaller, myBase);
}
if (PrintDebug) writeln("------------ Finish ------------ ");
if (PrintDebug) writeln("------------ Finish ------------");
}
void makeCalls(Caller myCaller, Base myBase) {
@ -97,6 +100,7 @@ void makeCalls(Caller myCaller, Base myBase) {
enforce(myCaller.ValCall(dh).val == dh.val, "[1] failed");
enforce(myCaller.RefCall(dh).val == dh.val, "[2] failed");
enforce(myCaller.PtrCall(dh).val == dh.val, "[3] failed");
enforce(myCaller.ConstPtrRefCall(dh).val == dh.val, "[3] failed");
// Fully overloaded method test (all methods in base class are overloaded)
enforce(myCaller.FullyOverloadedCall(10) == myBaseType ~ "::FullyOverloaded(int)", "[4] failed");
@ -137,6 +141,11 @@ public class DDerived : Base {
return x;
}
public override DoubleHolder ConstPtrRef(DoubleHolder x) {
if (PrintDebug) writefln("DDerived - ConstPtrRef(%s)", x.val);
return x;
}
public override string FullyOverloaded(int x) {
if (PrintDebug) writefln("DDerived - FullyOverloaded(int %s)", x);
return "DDerived::FullyOverloaded(int)";

View file

@ -0,0 +1,114 @@
module li_boost_shared_ptr_director_runme;
import std.conv;
import std.exception;
import std.stdio;
import std.string;
import li_boost_shared_ptr_director.li_boost_shared_ptr_director;
import li_boost_shared_ptr_director.Base;
import li_boost_shared_ptr_director.C;
void check(int got, int expected) {
enforce(got == expected, "Failed. got: " ~ to!string(got) ~ " Expected: " ~ to!string(expected));
}
void main() {
Derived a = new Derived(false);
Derived b = new Derived(true);
check(call_ret_c_shared_ptr(a), 1);
check(call_ret_c_shared_ptr(b), -1);
check(call_ret_c_by_value(a), 1);
check(call_ret_c_shared_ptr(a), 1);
check(call_ret_c_shared_ptr(b), -1);
check(call_ret_c_by_value(a), 1);
check(call_take_c_by_value(a), 5);
check(call_take_c_by_ref(a), 6);
check(call_take_c_by_pointer(a), 7);
check(call_take_c_by_pointer_ref(a), 8);
check(call_take_c_shared_ptr_by_value(a), 9);
check(call_take_c_shared_ptr_by_ref(a), 10);
check(call_take_c_shared_ptr_by_pointer(a), 11);
check(call_take_c_shared_ptr_by_pointer_ref(a), 12);
check(call_take_c_by_pointer_with_null(a), -2);
check(call_take_c_by_pointer_ref_with_null(a), -3);
check(call_take_c_shared_ptr_by_value_with_null(a), -4);
check(call_take_c_shared_ptr_by_ref_with_null(a), -5);
check(call_take_c_shared_ptr_by_pointer_with_null(a), -6);
check(call_take_c_shared_ptr_by_pointer_ref_with_null(a), -7);
}
public class Derived : Base {
private bool return_none;
public this(bool flag) {
super();
this.return_none = flag;
}
public override C ret_c_shared_ptr() {
if (this.return_none)
return null;
else
return new C();
}
public override C ret_c_by_value() {
return new C();
}
public override int take_c_by_value(C c) {
return c.get_m();
}
public override int take_c_by_ref(C c) {
return c.get_m();
}
public override int take_c_by_pointer(C c) {
if (c !is null)
return c.get_m();
else
return -2;
}
public override int take_c_by_pointer_ref(C c) {
if (c !is null)
return c.get_m();
else
return -3;
}
public override int take_c_shared_ptr_by_value(C c) {
if (c !is null)
return c.get_m();
else
return -4;
}
public override int take_c_shared_ptr_by_ref(C c) {
if (c !is null)
return c.get_m();
else
return -5;
}
public override int take_c_shared_ptr_by_pointer(C c) {
if (c !is null)
return c.get_m();
else
return -6;
}
public override int take_c_shared_ptr_by_pointer_ref(C c) {
if (c !is null)
return c.get_m();
else
return -7;
}
}

View file

@ -0,0 +1,30 @@
%module default_arg_expressions
%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) ptr;
%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) UsdGeomTokensPtr;
%immutable UsdGeomTokens;
%inline %{
struct Numbers {
int val;
int *ptr;
Numbers() : val(), ptr(&val) {}
};
struct TfToken {
Numbers val;
Numbers *ptr;
TfToken() : val(), ptr(&val) {}
};
struct Tokens {
const TfToken face;
const TfToken *pface;
Tokens() : face(), pface(&face) {}
};
static Tokens UsdGeomTokens;
static Tokens *UsdGeomTokensPtr = &UsdGeomTokens;
void CreateMaterialBindSubset1(const Tokens &elementType = UsdGeomTokens) {}
void CreateMaterialBindSubset2(int num = UsdGeomTokensPtr->pface->val.val) {}
void CreateMaterialBindSubset3(int num = UsdGeomTokensPtr->pface->ptr->val) {}
void CreateMaterialBindSubset4(int num = UsdGeomTokensPtr->face.val.val) {}
//void CreateMaterialBindSubset5(int num = UsdGeomTokens.face.val.val) {}
%}

View file

@ -28,6 +28,13 @@
int value_perm(int first, int mode = 0640 | 0004) { return mode; }
int value_m01(int first, int val = -01) { return val; }
bool booltest2(bool x = 0 | 1) { return x; }
int max_32bit_int1(int a = 0x7FFFFFFF) { return a; }
int max_32bit_int2(int a = 2147483647) { return a; }
int min_32bit_int1(int a = -0x80000000) { return a; }
long long too_big_32bit_int1(long long a = 0x80000000) { return a; }
long long too_big_32bit_int2(long long a = 2147483648LL) { return a; }
long long too_small_32bit_int1(long long a = -0x80000001) { return a; }
long long too_small_32bit_int2(long long a = -2147483649LL) { return a; }
};
void doublevalue1(int first, double num = 0.0e-1) {}

View file

@ -1,5 +1,13 @@
%module default_args_c
%{
#if defined(__clang__)
#pragma clang diagnostic push
// Suppress: use of logical '||' with constant operand
#pragma clang diagnostic ignored "-Wconstant-logical-operand"
#endif
%}
/* Default arguments for C code */
int foo1(int x = 42 || 3);
int foo43(int x = 42 | 3);

View file

@ -3,6 +3,7 @@
%warnfilter(SWIGWARN_TYPEMAP_THREAD_UNSAFE,SWIGWARN_TYPEMAP_DIRECTOROUT_PTR) Base::Ref;
%warnfilter(SWIGWARN_TYPEMAP_THREAD_UNSAFE,SWIGWARN_TYPEMAP_DIRECTOROUT_PTR) Base::Ptr;
%warnfilter(SWIGWARN_TYPEMAP_THREAD_UNSAFE,SWIGWARN_TYPEMAP_DIRECTOROUT_PTR) Base::ConstPtrRef;
%module(directors="1") director_classes
@ -43,6 +44,7 @@ public:
virtual DoubleHolder Val(DoubleHolder x) { if (PrintDebug) std::cout << "Base - Val(" << x.val << ")" << std::endl; return x; }
virtual DoubleHolder& Ref(DoubleHolder& x) { if (PrintDebug) std::cout << "Base - Ref(" << x.val << ")" << std::endl; return x; }
virtual DoubleHolder* Ptr(DoubleHolder* x) { if (PrintDebug) std::cout << "Base - Ptr(" << x->val << ")" << std::endl; return x; }
virtual DoubleHolder *const& ConstPtrRef(DoubleHolder *const& cprx) { if (PrintDebug) std::cout << "Base - ConstPtrRef(" << cprx->val << ")" << std::endl; return cprx; }
virtual std::string FullyOverloaded(int x) { if (PrintDebug) std::cout << "Base - FullyOverloaded(int " << x << ")" << std::endl; return "Base::FullyOverloaded(int)"; }
virtual std::string FullyOverloaded(bool x) { if (PrintDebug) std::cout << "Base - FullyOverloaded(bool " << x << ")" << std::endl; return "Base::FullyOverloaded(bool)"; }
@ -68,6 +70,7 @@ public:
virtual DoubleHolder Val(DoubleHolder x) { if (PrintDebug) std::cout << "Derived - Val(" << x.val << ")" << std::endl; return x; }
virtual DoubleHolder& Ref(DoubleHolder& x) { if (PrintDebug) std::cout << "Derived - Ref(" << x.val << ")" << std::endl; return x; }
virtual DoubleHolder* Ptr(DoubleHolder* x) { if (PrintDebug) std::cout << "Derived - Ptr(" << x->val << ")" << std::endl; return x; }
virtual DoubleHolder *const& ConstPtrRef(DoubleHolder *const& cprx) { if (PrintDebug) std::cout << "Derived - ConstPtrRef(" << cprx->val << ")" << std::endl; return cprx; }
virtual std::string FullyOverloaded(int x) { if (PrintDebug) std::cout << "Derived - FullyOverloaded(int " << x << ")" << std::endl; return "Derived::FullyOverloaded(int)"; }
virtual std::string FullyOverloaded(bool x) { if (PrintDebug) std::cout << "Derived - FullyOverloaded(bool " << x << ")" << std::endl; return "Derived::FullyOverloaded(bool)"; }
@ -99,6 +102,7 @@ public:
DoubleHolder ValCall(DoubleHolder x) { return m_base->Val(x); }
DoubleHolder& RefCall(DoubleHolder& x) { return m_base->Ref(x); }
DoubleHolder* PtrCall(DoubleHolder* x) { return m_base->Ptr(x); }
DoubleHolder *const& ConstPtrRefCall(DoubleHolder *const& cprx) { return m_base->ConstPtrRef(cprx); }
std::string FullyOverloadedCall(int x) { return m_base->FullyOverloaded(x); }
std::string FullyOverloadedCall(bool x) { return m_base->FullyOverloaded(x); }
std::string SemiOverloadedCall(int x) { return m_base->SemiOverloaded(x); }

View file

@ -20,14 +20,10 @@
#ifndef SWIG_DIRECTORS
namespace Swig {
class DirectorException {};
class DirectorMethodException: public Swig::DirectorException {};
class DirectorException {};
class DirectorMethodException: public Swig::DirectorException {};
}
#ifndef SWIG_fail
#define SWIG_fail
#endif
#endif /* !SWIG_DIRECTORS */
%}
%include "std_string.i"
@ -41,8 +37,8 @@ class DirectorMethodException: public Swig::DirectorException {};
}
%exception {
try { $action }
catch (Swig::DirectorException &) { SWIG_fail; }
try { $action }
catch (Swig::DirectorException &) { SWIG_fail; }
}
#endif
@ -56,8 +52,8 @@ class DirectorMethodException: public Swig::DirectorException {};
}
%exception {
try { $action }
catch (Swig::DirectorException &) { SWIG_fail; }
try { $action }
catch (Swig::DirectorException &) { SWIG_fail; }
}
#endif
@ -75,12 +71,12 @@ class DirectorMethodException: public Swig::DirectorException {};
// Change back to old 2.0 default behavior
%feature("director:except") {
jthrowable $error = jenv->ExceptionOccurred();
if ($error) {
// Dont clear exception, still be active when return to java execution
// Essentially ignore exception occurred -- old behavior.
return $null;
}
jthrowable $error = jenv->ExceptionOccurred();
if ($error) {
// Dont clear exception, still be active when return to java execution
// Essentially ignore exception occurred -- old behavior.
return $null;
}
}
#endif

View file

@ -0,0 +1,25 @@
%module(directors="1") director_exception_catches
%include <std_string.i>
%feature("director") BaseClass;
%{
// define dummy director exception classes to prevent spurious errors
// in target languages that do not support directors.
#ifndef SWIG_DIRECTORS
namespace Swig {
class DirectorException {};
}
#endif /* !SWIG_DIRECTORS */
%}
%catches(Swig::DirectorException) BaseClass::call_description;
%inline %{
struct BaseClass {
virtual std::string description() const = 0;
static std::string call_description(BaseClass& bc) { return bc.description(); }
virtual ~BaseClass() {}
};
%}

View file

@ -0,0 +1,72 @@
%module(directors="1") director_ownership
// Github issue #1184
%include "std_string.i"
%feature("director") example::ContentBase;
%feature("director") example::ContentDerived;
%newobject example::make_content;
%inline %{
#include <string>
namespace example
{
class ContentBase
{
public:
ContentBase() {}
virtual ~ContentBase() {}
virtual std::string get_name() const = 0;
};
class ContentDerived: public ContentBase
{
public:
ContentDerived():ContentBase() { m_name = "ContentDerived"; }
virtual ~ContentDerived() {}
virtual std::string get_name() const { return m_name; }
private:
std::string m_name;
};
class Container
{
public:
Container() { m_content = 0; }
~Container()
{
clear_content();
}
// the container takes the ownership of the content
void set_content(ContentBase* content)
{
clear_content();
m_content = content;
}
ContentBase* get_content() { return m_content; }
private:
void clear_content()
{
if(m_content)
{
delete m_content;
m_content = 0;
}
}
private:
ContentBase* m_content;
};
static ContentBase* make_content() { return new ContentDerived(); }
} // namespace example
%}

View file

@ -0,0 +1,4 @@
%module xxx
void bad(double nn = 5e);

View file

@ -0,0 +1,2 @@
cpp_invalid_exponents1.i:3: Error: Exponent does not have any digits
cpp_invalid_exponents1.i:3: Error: Syntax error in input(1).

View file

@ -0,0 +1,4 @@
%module xxx
void bad(double nn = 6.6e);

View file

@ -0,0 +1,2 @@
cpp_invalid_exponents2.i:3: Error: Exponent does not have any digits
cpp_invalid_exponents2.i:3: Error: Syntax error in input(1).

View file

@ -0,0 +1,51 @@
%module cpp_template_duplicate_names
// From test-suite/template_class_reuse.i test
%{
namespace Space {
template <bool B> struct Duplicate1 { void f(){}; };
}
%}
// %warnfilter(SWIGWARN_PARSE_REDEFINED) Space::Duplicate1;
namespace Space {
template <bool B> struct Duplicate1 { void f(){}; };
template <bool B> struct Duplicate1 { void f(){}; };
}
// %warnfilter(SWIGWARN_PARSE_REDEFINED) Space::Duplicate2;
%inline %{
namespace Space {
template <int I> struct Duplicate2 { void n(){}; };
}
%}
%template(Duplicate2_0) Space::Duplicate2<0>;
%template(Duplicate2_0) Space::Duplicate2<0>;
// %warnfilter(SWIGWARN_PARSE_REDEFINED) Space::Duplicate3;
%inline %{
namespace Space {
template <int I> struct Duplicate3 { void n(){}; };
}
%}
%template(Duplicate3) Space::Duplicate3<0>;
%template(Duplicate3) Space::Duplicate3<0>;
%{
namespace Space {
template <bool B> struct Duplicate4 { void f(){}; };
}
%}
// %warnfilter(SWIGWARN_PARSE_REDEFINED) Space::Duplicate4;
namespace Space {
template <bool B> struct Duplicate4 { void f(){}; };
template <bool B> struct Duplicate4 { void f(){}; };
}
%template(Duplicate4) Space::Duplicate4<0>;
%template(Duplicate4) Space::Duplicate4<0>;

View file

@ -0,0 +1,14 @@
cpp_template_duplicate_names.i:14: Warning 302: Identifier 'Duplicate1' redefined (ignored),
cpp_template_duplicate_names.i:13: Warning 302: previous definition of 'Duplicate1'.
cpp_template_duplicate_names.i:14: Warning 302: Identifier 'Duplicate1' redefined (ignored),
cpp_template_duplicate_names.i:13: Warning 302: previous definition of 'Duplicate1'.
cpp_template_duplicate_names.i:25: Warning 302: Identifier 'Duplicate2_0' redefined (ignored) (Renamed from 'Duplicate2< 0 >'),
cpp_template_duplicate_names.i:24: Warning 302: previous definition of 'Duplicate2_0' (Renamed from 'Duplicate2< 0 >').
cpp_template_duplicate_names.i:35: Warning 302: Identifier 'Duplicate3' redefined (ignored) (Renamed from 'Duplicate3< 0 >'),
cpp_template_duplicate_names.i:31: Warning 302: previous definition of 'Duplicate3'.
cpp_template_duplicate_names.i:47: Warning 302: Identifier 'Duplicate4' redefined (ignored),
cpp_template_duplicate_names.i:46: Warning 302: previous definition of 'Duplicate4'.
cpp_template_duplicate_names.i:47: Warning 302: Identifier 'Duplicate4' redefined (ignored),
cpp_template_duplicate_names.i:46: Warning 302: previous definition of 'Duplicate4'.
cpp_template_duplicate_names.i:50: Warning 302: Identifier 'Duplicate4' redefined (ignored) (Renamed from 'Duplicate4< 0 >'),
cpp_template_duplicate_names.i:46: Warning 302: previous definition of 'Duplicate4'.

View file

@ -0,0 +1,43 @@
%module xxx
/* Note: needs -Wextra to see these warnings */
/* Divide by zero */
#define ZERO 0
#if 1%ZERO
#endif
#if 2/ZERO
#endif
#if 1%(5-5)
#endif
#if 2/(55-55)
#endif
/* Floating point */
#if 1.2
#endif
#if 2e3
#endif
#if 0
#elif 8.8
#endif
/* Missing whitespace after preproc directive */
#if123
#endif
#if456e
#endif
#if 0
#warning This should not warn
#elif1
#warning This should also not warn
#endif
#if(1)
#warning Warning okay: #if(1)
#endif

View file

@ -0,0 +1,19 @@
pp_expressions_bad.i:7: Warning 202: Could not evaluate expression '1%ZERO'
pp_expressions_bad.i:7: Warning 202: Error: 'Modulo by zero in expression'
pp_expressions_bad.i:9: Warning 202: Could not evaluate expression '2/ZERO'
pp_expressions_bad.i:9: Warning 202: Error: 'Division by zero in expression'
pp_expressions_bad.i:12: Warning 202: Could not evaluate expression '1%(5-5)'
pp_expressions_bad.i:12: Warning 202: Error: 'Modulo by zero in expression'
pp_expressions_bad.i:14: Warning 202: Could not evaluate expression '2/(55-55)'
pp_expressions_bad.i:14: Warning 202: Error: 'Division by zero in expression'
pp_expressions_bad.i:18: Warning 202: Could not evaluate expression '1.2'
pp_expressions_bad.i:18: Warning 202: Error: 'Floating point constant in preprocessor expression'
pp_expressions_bad.i:21: Warning 202: Could not evaluate expression '2e3'
pp_expressions_bad.i:21: Warning 202: Error: 'Floating point constant in preprocessor expression'
pp_expressions_bad.i:25: Warning 202: Could not evaluate expression '8.8'
pp_expressions_bad.i:25: Warning 202: Error: 'Floating point constant in preprocessor expression'
pp_expressions_bad.i:29: Error: Unknown SWIG preprocessor directive: if123 (if this is a block of target language code, delimit it with %{ and %})
pp_expressions_bad.i:30: Error: Extraneous #endif.
pp_expressions_bad.i:32: Error: Unknown SWIG preprocessor directive: if456e (if this is a block of target language code, delimit it with %{ and %})
pp_expressions_bad.i:33: Error: Extraneous #endif.
pp_expressions_bad.i:42: Warning 204: CPP #warning, "Warning okay: #if(1)".

View file

@ -0,0 +1,7 @@
%module xxx
#if 123e
#endif
#if 456.e
#endif

View file

@ -0,0 +1,6 @@
:EOF: Error: Exponent does not have any digits
pp_invalid_exponents.i:3: Warning 202: Could not evaluate expression '123e'
pp_invalid_exponents.i:3: Warning 202: Error: 'Syntax error'
:EOF: Error: Exponent does not have any digits
pp_invalid_exponents.i:6: Warning 202: Could not evaluate expression '456.e'
pp_invalid_exponents.i:6: Warning 202: Error: 'Syntax error'

View file

@ -6,6 +6,10 @@
#if defined(_MSC_VER)
#pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
#endif
#if __GNUC__ >= 7
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated" // dynamic exception specifications are deprecated in C++11
#endif
%}
%{
@ -49,3 +53,11 @@ class Impl
#warning "UTL needs fixing for partial exception information"
#endif
%{
#if defined(_MSC_VER)
#pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
#endif
#if __GNUC__ >= 7
#pragma GCC diagnostic pop
#endif
%}

View file

@ -14,8 +14,8 @@
(check (=~ (foo 1 2 "bar" 4) 15))
;; Check second method
(check (=~ (foo 1 2) 4811.4))
(check (=~ (foo 1 2 3.2) 4797.2))
(check (=~ (foo 1 2 3.2 #\Q) 4798.2))
(check (=~ (foo 1 2) 118))
(check (=~ (foo 1 2 3.2) 104))
(check (=~ (foo 1 2 3.2 #\Q) 4798))
(exit 0)

View file

@ -44,6 +44,10 @@ template<class T> class vector {
#if defined(_MSC_VER)
#pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
#endif
#if __GNUC__ >= 7
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated" // dynamic exception specifications are deprecated in C++11
#endif
class Base {
public:
@ -70,6 +74,9 @@ public:
#if defined(_MSC_VER)
#pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
#endif
#if __GNUC__ >= 7
#pragma GCC diagnostic pop
#endif
%}
%template(maxint) maximum<int>;

View file

@ -47,6 +47,10 @@ CPP_TEST_CASES = \
# li_boost_intrusive_ptr
CPP11_TEST_CASES = \
cpp11_shared_ptr_const \
cpp11_shared_ptr_nullptr_in_containers \
cpp11_shared_ptr_overload \
cpp11_shared_ptr_upcast \
cpp11_strongly_typed_enumerations_simple \
DOXYGEN_TEST_CASES := \

View file

@ -22,7 +22,7 @@ public class class_scope_namespace_runme {
F f = new F();
G g = new G();
H.HH h = new H.HH();
I.II i = new I.II();
I_.II i = new I_.II();
J j = new J();
K k = new K();
L l = new L();

View file

@ -0,0 +1,60 @@
import cpp11_shared_ptr_overload.*;
public class cpp11_shared_ptr_overload_runme {
static {
try {
System.loadLibrary("cpp11_shared_ptr_overload");
} catch (UnsatisfiedLinkError e) {
System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
System.exit(1);
}
}
public static void main(String argv[])
{
String ret = null;
// ref
ret = cpp11_shared_ptr_overload.UseA(new MyType("123"));
if (!ret.equals("123 ref")) throw new RuntimeException("UseA fail:" + ret);
ret = cpp11_shared_ptr_overload.UseB(0, new MyType("123"));
if (!ret.equals("123 ref")) throw new RuntimeException("UseB fail:" + ret);
ret = cpp11_shared_ptr_overload.UseC(0, new MyType("123"), new MyType("456"));
if (!ret.equals("123 ref")) throw new RuntimeException("UseC fail:" + ret);
// sharedptr
ret = cpp11_shared_ptr_overload.UseX(new MyType("123"));
if (!ret.equals("123 sharedptr")) throw new RuntimeException("UseX fail:" + ret);
ret = cpp11_shared_ptr_overload.UseY(0, new MyType("123"));
if (!ret.equals("123 sharedptr")) throw new RuntimeException("UseY fail:" + ret);
ret = cpp11_shared_ptr_overload.UseZ(0, new MyType("123"), new MyType("456"));
if (!ret.equals("123 sharedptr")) throw new RuntimeException("UseZ fail:" + ret);
// Combo1-4
ret = cpp11_shared_ptr_overload.Combo1(new MyType("XXX"));
if (!ret.equals("XXXCombo1")) throw new RuntimeException("Combo1 fail:" + ret);
ret = cpp11_shared_ptr_overload.Combo2(new MyType("XXX"));
if (!ret.equals("XXXCombo2")) throw new RuntimeException("Combo2 fail:" + ret);
ret = cpp11_shared_ptr_overload.Combo3(new MyType("XXX"));
if (!ret.equals("XXXCombo3")) throw new RuntimeException("Combo3 fail:" + ret);
ret = cpp11_shared_ptr_overload.Combo4(new MyType("XXX"));
if (!ret.equals("XXXCombo4")) throw new RuntimeException("Combo4 fail:" + ret);
// Combo5-7
ret = cpp11_shared_ptr_overload.Combo5(new MyType("XXX"));
if (!ret.equals("XXXCombo5")) throw new RuntimeException("Combo5 fail:" + ret);
ret = cpp11_shared_ptr_overload.Combo6(new MyType("XXX"));
if (!ret.equals("XXXCombo6")) throw new RuntimeException("Combo6 fail:" + ret);
ret = cpp11_shared_ptr_overload.Combo7(new MyType("XXX"));
if (!ret.equals("XXXCombo7")) throw new RuntimeException("Combo7 fail:" + ret);
}
}

View file

@ -16,6 +16,7 @@ Expected output if PrintDebug enabled:
Base - Val(444.555)
Base - Ref(444.555)
Base - Ptr(444.555)
Base - ConstPtrRef(444.555)
Base - FullyOverloaded(int 10)
Base - FullyOverloaded(bool 1)
Base - SemiOverloaded(int -678)
@ -26,6 +27,7 @@ Base - DefaultParms(10, 1.1)
Derived - Val(444.555)
Derived - Ref(444.555)
Derived - Ptr(444.555)
Derived - ConstPtrRef(444.555)
Derived - FullyOverloaded(int 10)
Derived - FullyOverloaded(bool 1)
Derived - SemiOverloaded(int -678)
@ -36,6 +38,7 @@ Derived - DefaultParms(10, 1.1)
JavaDerived - Val(444.555)
JavaDerived - Ref(444.555)
JavaDerived - Ptr(444.555)
JavaDerived - ConstPtrRef(444.555)
JavaDerived - FullyOverloaded(int 10)
JavaDerived - FullyOverloaded(bool True)
JavaDerived - SemiOverloaded(-678)
@ -67,7 +70,7 @@ public class director_classes_runme {
void run()
{
if (director_classes.getPrintDebug()) System.out.println("------------ Start ------------ ");
if (director_classes.getPrintDebug()) System.out.println("------------ Start ------------");
Caller myCaller = new Caller();
@ -96,7 +99,7 @@ public class director_classes_runme {
myBase.delete();
}
if (director_classes.getPrintDebug()) System.out.println("------------ Finish ------------ ");
if (director_classes.getPrintDebug()) System.out.println("------------ Finish ------------");
}
void makeCalls(Caller myCaller, Base myBase)
@ -111,6 +114,7 @@ public class director_classes_runme {
if (myCaller.ValCall(dh).getVal() != dh.getVal()) throw new RuntimeException("failed");
if (myCaller.RefCall(dh).getVal() != dh.getVal()) throw new RuntimeException("failed");
if (myCaller.PtrCall(dh).getVal() != dh.getVal()) throw new RuntimeException("failed");
if (myCaller.ConstPtrRefCall(dh).getVal() != dh.getVal()) throw new RuntimeException("failed");
// Fully overloaded method test (all methods in base class are overloaded)
if (!myCaller.FullyOverloadedCall(10).equals(baseSimpleName + "::FullyOverloaded(int)")) {
@ -170,6 +174,11 @@ class JavaDerived extends Base
if (director_classes.getPrintDebug()) System.out.println("JavaDerived - Ptr(" + x.getVal() + ")");
return x;
}
public DoubleHolder ConstPtrRef(DoubleHolder x)
{
if (director_classes.getPrintDebug()) System.out.println("JavaDerived - ConstPtrRef(" + x.getVal() + ")");
return x;
}
public String FullyOverloaded(int x)
{
if (director_classes.getPrintDebug()) System.out.println("JavaDerived - FullyOverloaded(int " + x + ")");

View file

@ -0,0 +1,35 @@
import director_exception_catches.*;
public class director_exception_catches_runme {
static {
try {
System.loadLibrary("director_exception_catches");
} catch (UnsatisfiedLinkError e) {
System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
System.exit(1);
}
}
public static void main(String argv[]) {
BaseClass b = new director_exception_catches_MyClass();
try {
String s = BaseClass.call_description(b);
throw new RuntimeException("Failed to catch exception");
} catch (NullPointerException e) {
if (!e.getMessage().startsWith("Testing exception thrown in BaseClass.description"))
throw new RuntimeException("Unexpected exception message: " + e.getMessage());
}
}
}
class director_exception_catches_MyClass extends BaseClass {
@Override
public String description() {
throw new NullPointerException("Testing exception thrown in BaseClass.description");
}
}

View file

@ -0,0 +1,42 @@
import director_ownership.*;
public class director_ownership_runme {
static {
try {
System.loadLibrary("director_ownership");
} catch (UnsatisfiedLinkError e) {
System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
System.exit(1);
}
}
public static void set_content_and_release(Container container, ContentBase content) {
content.swigReleaseOwnership();
container.set_content(content);
}
public static void main(String argv[]) {
Container container = new Container();
// make a content in java (cMemoryOwn true)
ContentBase content_java = new ContentDerived();
// make a content in c++ (cMemoryOwn true)
ContentBase content_cpp = director_ownership.make_content();
set_content_and_release(container, content_java);
if (!container.get_content().get_name().equals("ContentDerived"))
throw new RuntimeException("did not get ContentDerived");
// when swigReleaseOwnership() is called on content_cpp, swig tries a static_cast to director and calls the method
// director->swig_java_change_ownership. The content created in c++ native library is not a director, therefore a
// segfault may occur.
// With a check done using dynamic_cast this issue could be avoided.
set_content_and_release(container, content_cpp);
if (!container.get_content().get_name().equals("ContentDerived"))
throw new RuntimeException("did not get ContentDerived");
}
}

View file

@ -126,19 +126,28 @@ public class java_director_exception_feature_nspace_runme {
try { b.genericpong(1); fail("No exception thrown in genericpong(1)"); }
catch (MyJavaException1 e) {
failif( ! java_director_exception_feature_nspace_Consts.GENERICPONGEXCP1.equals(e.getMessage()), "Expected exception has unexpected message: '" + e.getMessage() + "'");
StackTraceElement[] st = e.getStackTrace();
failif( st.length != 5, "Stack length is only " + st.length);
failif( ! st[0].toString().startsWith("java_director_exception_feature_nspace_MyFooDirectorImpl.genericpong(java_director_exception_feature_nspace_runme.java:"), "Incorrect top of stack: " + st[0]);
}
try { b.genericpong(2); fail("No exception thrown in genericpong(2)");}
catch (java_director_exception_feature_nspace_NewCheckedException e) {
failif( ! java_director_exception_feature_nspace_Consts.GENERICPONGEXCP2.equals(e.getMessage()), "Expected exception has unexpected message: '" + e.getMessage() + "'");
StackTraceElement[] st = e.getStackTrace();
failif( st.length != 5, "Stack length is only " + st.length);
failif( ! st[0].toString().startsWith("java_director_exception_feature_nspace_MyFooDirectorImpl.genericpong(java_director_exception_feature_nspace_runme.java:"), "Incorrect top of stack: " + st[0]);
}
try { b.genericpong(3); fail("No exception thrown in genericpong(3)");}
catch (java_director_exception_feature_nspace_NewUncheckedException e) {
failif( ! java_director_exception_feature_nspace_Consts.GENERICPONGEXCP3.equals(e.getMessage()), "Expected exception has unexpected message: '" + e.getMessage() + "'");
StackTraceElement[] st = e.getStackTrace();
failif( st.length != 5, "Stack length is only " + st.length);
failif( ! st[0].toString().startsWith("java_director_exception_feature_nspace_MyFooDirectorImpl.genericpong(java_director_exception_feature_nspace_runme.java:"), "Incorrect top of stack: " + st[0]);
}
try { b.genericpong(4); fail("No exception thrown in genericpong(4)");}
catch (RuntimeException e) {
failif ( e.getClass() != RuntimeException.class, "Exception " + e + " is not exactly RumtimeException");
failif( ! java_director_exception_feature_nspace_Consts.GENERICPONGEXCP4.equals(e.getMessage()), "Expected exception has unexpected message: '" + e.getMessage() + "'");
failif ( e.getClass() != RuntimeException.class, "Exception " + e + " is not exactly RuntimeException");
failif( ! "Unspecified DirectorException message".equals(e.getMessage()), "Expected exception has unexpected message: '" + e.getMessage() + "'");
}
}
catch (Exception e) {

View file

@ -127,19 +127,28 @@ public class java_director_exception_feature_runme {
try { b.genericpong(1); fail("No exception thrown in genericpong(1)"); }
catch (MyJavaException1 e) {
failif( ! java_director_exception_feature_Consts.GENERICPONGEXCP1.equals(e.getMessage()), "Expected exception has unexpected message: '" + e.getMessage() + "'");
StackTraceElement[] st = e.getStackTrace();
failif( st.length != 5, "Stack length is only " + st.length);
failif( ! st[0].toString().startsWith("java_director_exception_feature_MyFooDirectorImpl.genericpong(java_director_exception_feature_runme.java:"), "Incorrect top of stack: " + st[0]);
}
try { b.genericpong(2); fail("No exception thrown in genericpong(2)");}
catch (NewCheckedException e) {
failif( ! java_director_exception_feature_Consts.GENERICPONGEXCP2.equals(e.getMessage()), "Expected exception has unexpected message: '" + e.getMessage() + "'");
StackTraceElement[] st = e.getStackTrace();
failif( st.length != 5, "Stack length is only " + st.length);
failif( ! st[0].toString().startsWith("java_director_exception_feature_MyFooDirectorImpl.genericpong(java_director_exception_feature_runme.java:"), "Incorrect top of stack: " + st[0]);
}
try { b.genericpong(3); fail("No exception thrown in genericpong(3)");}
catch (NewUncheckedException e) {
failif( ! java_director_exception_feature_Consts.GENERICPONGEXCP3.equals(e.getMessage()), "Expected exception has unexpected message: '" + e.getMessage() + "'");
StackTraceElement[] st = e.getStackTrace();
failif( st.length != 5, "Stack length is only " + st.length);
failif( ! st[0].toString().startsWith("java_director_exception_feature_MyFooDirectorImpl.genericpong(java_director_exception_feature_runme.java:"), "Incorrect top of stack: " + st[0]);
}
try { b.genericpong(4); fail("No exception thrown in genericpong(4)");}
catch (RuntimeException e) {
failif ( e.getClass() != RuntimeException.class, "Exception " + e + " is not exactly RumtimeException");
failif( ! java_director_exception_feature_Consts.GENERICPONGEXCP4.equals(e.getMessage()), "Expected exception has unexpected message: '" + e.getMessage() + "'");
failif ( e.getClass() != RuntimeException.class, "Exception " + e + " is not exactly RuntimeException");
failif( ! "Unspecified DirectorException message".equals(e.getMessage()), "Expected exception has unexpected message: '" + e.getMessage() + "'");
}
}

View file

@ -93,6 +93,28 @@ public class java_throws_runme {
if (!pass)
throw new RuntimeException("Test 6 failed");
// Interface function
pass = false;
try {
InterfaceTestImpl iti = new InterfaceTestImpl();
iti.imethod(true);
}
catch (MyException e) { pass = true; }
if (!pass)
throw new RuntimeException("Test interface 1 failed");
pass = false;
try {
InterfaceTestImpl iti = new InterfaceTestImpl();
iti.imethod(false);
pass = true;
}
catch (MyException e) { pass = false; }
if (!pass)
throw new RuntimeException("Test interface 2 failed");
// Global function
pass = false;
try {

View file

@ -1,60 +1,129 @@
public class li_boost_shared_ptr_runme {
import li_boost_shared_ptr_director.*;
public class li_boost_shared_ptr_director_runme {
static {
try {
System.loadLibrary("li_boost_shared_ptr");
System.loadLibrary("li_boost_shared_ptr_director");
} catch (UnsatisfiedLinkError e) {
System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
System.exit(1);
}
}
private static void check(String got, String expected) {
if (!got.equals(expected))
private static void check(int got, int expected) {
if (got != expected)
throw new RuntimeException("Failed, got: " + got + " expected: " + expected);
}
public static void main(String argv[]) {
li_boost_shared_ptr_director_Derived a = li_boost_shared_ptr_director_Derived.new(false);
li_boost_shared_ptr_director_Derived b = li_boost_shared_ptr_director_Derived.new(true);
li_boost_shared_ptr_director_Derived a = new li_boost_shared_ptr_director_Derived(false);
li_boost_shared_ptr_director_Derived b = new li_boost_shared_ptr_director_Derived(true);
check(call_ret_c_shared_ptr(a) == 1);
check(call_ret_c_shared_ptr(b) == -1);
check(call_ret_c_by_value(a) == 1);
check(li_boost_shared_ptr_director.call_ret_c_shared_ptr(a), 1);
check(li_boost_shared_ptr_director.call_ret_c_shared_ptr(b), -1);
check(li_boost_shared_ptr_director.call_ret_c_by_value(a), 1);
check(call_take_c_by_value(a) == 5);
check(call_take_c_shared_ptr_by_value(a) == 6);
check(call_take_c_shared_ptr_by_ref(a) == 7);
check(call_take_c_shared_ptr_by_pointer(a) == 8);
check(call_take_c_shared_ptr_by_pointer_ref(a) == 9);
check(li_boost_shared_ptr_director.call_ret_c_shared_ptr(a), 1);
check(li_boost_shared_ptr_director.call_ret_c_shared_ptr(b), -1);
check(li_boost_shared_ptr_director.call_ret_c_by_value(a), 1);
check(call_take_c_shared_ptr_by_value_with_null(a) == -2);
check(call_take_c_shared_ptr_by_ref_with_null(a) == -3);
check(call_take_c_shared_ptr_by_pointer_with_null(a) == -4);
check(call_take_c_shared_ptr_by_pointer_ref_with_null(a) == -5);
check(li_boost_shared_ptr_director.call_take_c_by_value(a), 5);
check(li_boost_shared_ptr_director.call_take_c_by_ref(a), 6);
check(li_boost_shared_ptr_director.call_take_c_by_pointer(a), 7);
check(li_boost_shared_ptr_director.call_take_c_by_pointer_ref(a), 8);
check(li_boost_shared_ptr_director.call_take_c_shared_ptr_by_value(a), 9);
check(li_boost_shared_ptr_director.call_take_c_shared_ptr_by_ref(a), 10);
check(li_boost_shared_ptr_director.call_take_c_shared_ptr_by_pointer(a), 11);
check(li_boost_shared_ptr_director.call_take_c_shared_ptr_by_pointer_ref(a), 12);
check(li_boost_shared_ptr_director.call_take_c_by_pointer_with_null(a), -2);
check(li_boost_shared_ptr_director.call_take_c_by_pointer_ref_with_null(a), -3);
check(li_boost_shared_ptr_director.call_take_c_shared_ptr_by_value_with_null(a), -4);
check(li_boost_shared_ptr_director.call_take_c_shared_ptr_by_ref_with_null(a), -5);
check(li_boost_shared_ptr_director.call_take_c_shared_ptr_by_pointer_with_null(a), -6);
check(li_boost_shared_ptr_director.call_take_c_shared_ptr_by_pointer_ref_with_null(a), -7);
}
}
class li_boost_shared_ptr_director_Derived extends li_boost_shared_ptr_director.Base {
class li_boost_shared_ptr_director_Derived extends Base {
@Override
public String ping() {
return "li_boost_shared_ptr_director_MyBarFoo.ping()";
private boolean return_none;
li_boost_shared_ptr_director_Derived(boolean flag) {
super();
this.return_none = flag;
}
@Override
public String pong() {
return "li_boost_shared_ptr_director_MyBarFoo.pong();" + ping();
public C ret_c_shared_ptr() {
if (this.return_none)
return null;
else
return new C();
}
@Override
public String upcall(li_boost_shared_ptr_director.FooBar fooBarPtr) {
return "override;" + fooBarPtr.FooBarDo();
public C ret_c_by_value() {
return new C();
}
@Override
public li_boost_shared_ptr_director.Foo makeFoo() {
return new li_boost_shared_ptr_director.Foo();
public int take_c_by_value(C c) {
return c.get_m();
}
@Override
public int take_c_by_ref(C c) {
return c.get_m();
}
@Override
public int take_c_by_pointer(C c) {
if (c != null)
return c.get_m();
else
return -2;
}
@Override
public int take_c_by_pointer_ref(C c) {
if (c != null)
return c.get_m();
else
return -3;
}
@Override
public int take_c_shared_ptr_by_value(C c) {
if (c != null)
return c.get_m();
else
return -4;
}
@Override
public int take_c_shared_ptr_by_ref(C c) {
if (c != null)
return c.get_m();
else
return -5;
}
@Override
public int take_c_shared_ptr_by_pointer(C c) {
if (c != null)
return c.get_m();
else
return -6;
}
@Override
public int take_c_shared_ptr_by_pointer_ref(C c) {
if (c != null)
return c.get_m();
else
return -7;
}
}

View file

@ -0,0 +1,57 @@
import template_class_reuse_name.*;
public class template_class_reuse_name_runme {
static {
try {
System.loadLibrary("template_class_reuse_name");
} catch (UnsatisfiedLinkError e) {
System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
System.exit(1);
}
}
public static void main(String argv[])
{
new Bool1().tt();
new Bool1False().ff();
new Bool2().tt();
new Bool2False().ff();
new Bool3().tt();
new Bool3False().ff();
new Bool4().tt();
new Bool4False().ff();
new BoolForward1().tt();
new BoolForward1False().ff();
new BoolForward2().tt();
new BoolForward2False().ff();
new BoolForward3().tt();
new BoolForward3False().ff();
new BoolForward4().tt();
new BoolForward4False().ff();
new IntBool1().tt();
new IntBool1False().ff();
new IntBool2().tt();
new IntBool2False().ff();
new IntBool3().tt();
new IntBool3False().ff();
new IntBool4().tt();
new IntBool4False().ff();
new Duplicate2_0().n();
new Duplicate3().n();
}
}

View file

@ -23,10 +23,10 @@ public class template_partial_specialization_runme {
new G().g();
new H().h();
new I().i();
new J().j();
new K().k();
new L().l();
new M().m();
new N().n();
new BB().b();
new BBB().b();

View file

@ -23,10 +23,10 @@ public class template_partial_specialization_typedef_runme {
new G().g();
new H().h();
new I().i();
new J().j();
new K().k();
new L().l();
new M().m();
new N().n();
new BB().b();
new BBB().b();

View file

@ -0,0 +1,26 @@
import typedef_classforward_same_name.*;
public class typedef_classforward_same_name_runme {
static {
try {
System.loadLibrary("typedef_classforward_same_name");
} catch (UnsatisfiedLinkError e) {
System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
System.exit(1);
}
}
public static void main(String argv[]) {
Foo foo = new Foo();
foo.setX(5);
if (typedef_classforward_same_name.extractFoo(foo) != 5)
throw new RuntimeException("unexpected value");
Boo boo = new Boo();
boo.setX(5);
if (typedef_classforward_same_name.extractBoo(boo) != 5)
throw new RuntimeException("unexpected value");
}
}

View file

@ -42,7 +42,6 @@
%feature("director:except") MyNS::Foo::ping {
jthrowable $error = jenv->ExceptionOccurred();
if ($error) {
jenv->ExceptionClear(); // clear java exception since mapping to c++ exception
if (Swig::ExceptionMatches(jenv,$error,"$packagepath/MyJavaException1")) {
throw 1;
} else if (Swig::ExceptionMatches(jenv,$error,"$packagepath/MyJavaException2")) {
@ -71,7 +70,6 @@
%feature("director:except") MyNS::Foo::pong %{
jthrowable $error = jenv->ExceptionOccurred();
if ($error) {
jenv->ExceptionClear();
$directorthrowshandlers
throw ::MyNS::Unexpected(Swig::JavaExceptionMessage(jenv,$error).message());
}
@ -121,7 +119,10 @@
%feature("director:except") MyNS::Foo::genericpong {
jthrowable $error = jenv->ExceptionOccurred();
if ($error) {
jenv->ExceptionClear();
if (Swig::ExceptionMatches(jenv,$error,"UnconstructableException")) {
// Purposefully test NULL
throw Swig::DirectorException(jenv, NULL);
}
throw Swig::DirectorException(jenv,$error);
}
}
@ -131,9 +132,10 @@
%}
%feature ("except",throws="Exception") MyNS::Bar::genericpong %{
try { $action }
catch (Swig::DirectorException & direxcp) {
direxcp.raiseJavaException(jenv); // jenv always available in JNI code
try {
$action
} catch (Swig::DirectorException & direxcp) {
direxcp.throwException(jenv); // jenv always available in JNI code
return $null;
}
%}

Some files were not shown because too many files have changed in this diff Show more