Merge branch 'master' into doxygen
This commit is contained in:
commit
b7f78dd5a7
232 changed files with 5648 additions and 2419 deletions
25
.travis.yml
25
.travis.yml
|
|
@ -154,6 +154,11 @@ matrix:
|
||||||
env: SWIGLANG=python PY3=3 VER=3.5
|
env: SWIGLANG=python PY3=3 VER=3.5
|
||||||
sudo: required
|
sudo: required
|
||||||
dist: trusty
|
dist: trusty
|
||||||
|
- compiler: gcc
|
||||||
|
os: linux
|
||||||
|
env: SWIGLANG=python PY3=3 VER=3.6
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
os: linux
|
os: linux
|
||||||
env: SWIGLANG=python SWIG_FEATURES=-builtin VER=2.6
|
env: SWIGLANG=python SWIG_FEATURES=-builtin VER=2.6
|
||||||
|
|
@ -165,11 +170,11 @@ matrix:
|
||||||
sudo: required
|
sudo: required
|
||||||
dist: trusty
|
dist: trusty
|
||||||
- os: linux
|
- 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
|
sudo: required
|
||||||
dist: trusty
|
dist: trusty
|
||||||
- os: linux
|
- 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
|
sudo: required
|
||||||
dist: trusty
|
dist: trusty
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
|
|
@ -184,7 +189,12 @@ matrix:
|
||||||
dist: trusty
|
dist: trusty
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
os: linux
|
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
|
sudo: required
|
||||||
dist: trusty
|
dist: trusty
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
|
|
@ -279,6 +289,14 @@ matrix:
|
||||||
env: SWIGLANG=tcl SWIG_CC=gcc-6 SWIG_CXX=g++-6 CPP14=1
|
env: SWIGLANG=tcl SWIG_CC=gcc-6 SWIG_CXX=g++-6 CPP14=1
|
||||||
sudo: required
|
sudo: required
|
||||||
dist: trusty
|
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
|
- compiler: gcc
|
||||||
os: osx
|
os: osx
|
||||||
env: SWIGLANG=
|
env: SWIGLANG=
|
||||||
|
|
@ -349,6 +367,7 @@ install:
|
||||||
- if test "$TRAVIS_OS_NAME" = "osx"; then source Tools/travis-osx-install.sh; fi
|
- 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 "$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 "$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 $CC)
|
||||||
- ls -la $(which $CXX)
|
- ls -la $(which $CXX)
|
||||||
- $CC --version
|
- $CC --version
|
||||||
|
|
|
||||||
2
CHANGES
2
CHANGES
|
|
@ -11813,7 +11813,7 @@ Version 1.3.23 (November 11, 2004)
|
||||||
ie, no additional pointer elements are created, and
|
ie, no additional pointer elements are created, and
|
||||||
the original 'foo' and 'A.bar' can be used as parameters.
|
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:
|
to use the special variable Class::<fnc_name>_cb_ptr, ie:
|
||||||
|
|
||||||
foobarm(3, a, A.barm_cb_ptr)
|
foobarm(3, a, A.barm_cb_ptr)
|
||||||
|
|
|
||||||
223
CHANGES.current
223
CHANGES.current
|
|
@ -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)
|
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
|
2017-09-18: wsfulton
|
||||||
Fix type promotion wrapping constant expressions of the form:
|
Fix type promotion wrapping constant expressions of the form:
|
||||||
# define EXPR_MIXED1 (0x80 + 11.1) - 1
|
# 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
|
cpp_class_definition.i:5: Error: 'Space1::A' resolves to 'Space1::A' and
|
||||||
was incorrectly instantiated in scope 'Space2' instead of within scope 'Space1'.
|
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
|
2017-08-16: wsfulton
|
||||||
Fix scope lookup for template parameters containing unary scope operators.
|
Fix scope lookup for template parameters containing unary scope operators.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2019,37 +2019,50 @@ public class Container : global::System.IDisposable {
|
||||||
// Ensure that the GC doesn't collect any Element set from C#
|
// Ensure that the GC doesn't collect any Element set from C#
|
||||||
// as the underlying C++ class stores a shallow copy
|
// as the underlying C++ class stores a shallow copy
|
||||||
private Element elementReference;
|
private Element elementReference;
|
||||||
private global::System.Runtime.InteropServices.HandleRef getCPtrAndAddReference(Element element) {
|
|
||||||
elementReference = element;
|
|
||||||
return Element.getCPtr(element);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setElement(Element e) {
|
public void setElement(Element e) {
|
||||||
examplePINVOKE.Container_setElement(swigCPtr, getCPtrAndAddReference(e));
|
examplePINVOKE.Container_setElement(swigCPtr, Element.getCPtr(e));
|
||||||
|
elementReference = e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The following typemaps will generate the desired code.
|
The following typemaps can be used to generate this 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.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
%typemap(csin) Element *e "getCPtrAndAddReference($csinput)"
|
|
||||||
|
|
||||||
%typemap(cscode) Container %{
|
%typemap(cscode) Container %{
|
||||||
// Ensure that the GC doesn't collect any Element set from C#
|
// Ensure that the GC doesn't collect any Element set from C#
|
||||||
// as the underlying C++ class stores a shallow copy
|
// as the underlying C++ class stores a shallow copy
|
||||||
private Element elementReference;
|
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>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -269,6 +269,11 @@
|
||||||
<li><a href="SWIGPlus.html#SWIGPlus_nn35">Using declarations and inheritance</a>
|
<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_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_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>
|
<li><a href="SWIGPlus.html#SWIGPlus_nn42">Where to go for more information</a>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -381,6 +386,7 @@
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="Library.html#Library_shared_ptr_basics">shared_ptr basics</a>
|
<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_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_templates">shared_ptr and templates</a>
|
||||||
<li><a href="Library.html#Library_shared_ptr_directors">shared_ptr and directors</a>
|
<li><a href="Library.html#Library_shared_ptr_directors">shared_ptr and directors</a>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
@ -478,7 +484,7 @@
|
||||||
<li><a href="Typemaps.html#Typemaps_nn35">"memberin" typemap</a>
|
<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_nn36">"varin" typemap</a>
|
||||||
<li><a href="Typemaps.html#Typemaps_nn37">"varout" 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>
|
</ul>
|
||||||
<li><a href="Typemaps.html#Typemaps_nn39">Some typemap examples</a>
|
<li><a href="Typemaps.html#Typemaps_nn39">Some typemap examples</a>
|
||||||
<ul>
|
<ul>
|
||||||
|
|
@ -500,6 +506,9 @@
|
||||||
<li><a href="Typemaps.html#Typemaps_runtime_type_checker_usage">Usage</a>
|
<li><a href="Typemaps.html#Typemaps_runtime_type_checker_usage">Usage</a>
|
||||||
</ul>
|
</ul>
|
||||||
<li><a href="Typemaps.html#Typemaps_overloading">Typemaps and overloading</a>
|
<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_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_nn47">Passing data between typemaps</a>
|
||||||
<li><a href="Typemaps.html#Typemaps_nn52">C++ "this" pointer</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_threading">Director threading issues</a>
|
||||||
<li><a href="Java.html#Java_directors_performance">Director performance tuning</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>
|
<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>
|
</ul>
|
||||||
<li><a href="Java.html#Java_allprotected">Accessing protected members</a>
|
<li><a href="Java.html#Java_allprotected">Accessing protected members</a>
|
||||||
<li><a href="Java.html#Java_common_customization">Common customization features</a>
|
<li><a href="Java.html#Java_common_customization">Common customization features</a>
|
||||||
|
|
|
||||||
|
|
@ -94,6 +94,9 @@
|
||||||
<li><a href="#Java_directors_threading">Director threading issues</a>
|
<li><a href="#Java_directors_threading">Director threading issues</a>
|
||||||
<li><a href="#Java_directors_performance">Director performance tuning</a>
|
<li><a href="#Java_directors_performance">Director performance tuning</a>
|
||||||
<li><a href="#Java_exceptions_from_directors">Java exceptions from directors</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>
|
</ul>
|
||||||
<li><a href="#Java_allprotected">Accessing protected members</a>
|
<li><a href="#Java_allprotected">Accessing protected members</a>
|
||||||
<li><a href="#Java_common_customization">Common customization features</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">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
public class DirectorDerived extends DirectorBase {
|
class DirectorDerived extends DirectorBase {
|
||||||
public DirectorDerived() {
|
@Override
|
||||||
}
|
|
||||||
|
|
||||||
public void upcall_method() {
|
public void upcall_method() {
|
||||||
System.out.println("DirectorDerived::upcall_method() invoked.");
|
System.out.println("DirectorDerived.upcall_method() invoked.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
|
|
@ -3774,7 +3775,7 @@ will result in the following being output:
|
||||||
|
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
DirectorDerived::upcall_method() invoked.
|
DirectorDerived.upcall_method() invoked.
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -3825,45 +3826,186 @@ The disadvantage is that invocation of director methods from C++ when Java doesn
|
||||||
<p>
|
<p>
|
||||||
With directors routing method calls to Java, and proxies routing them
|
With directors routing method calls to Java, and proxies routing them
|
||||||
to C++, the handling of exceptions is an important concern.
|
to C++, the handling of exceptions is an important concern.
|
||||||
The default behavior from SWIG 3.0
|
The default behavior for Java exceptions thrown in a director method overridden in Java is
|
||||||
onwards is to convert the thrown Java exception into a SWIG defined
|
to store the thrown Java exception into a SWIG defined
|
||||||
<code>DirectorException</code> C++ exception.
|
<code>Swig::DirectorException</code> C++ class exception in the C++ layer and then throw this C++ exception.
|
||||||
SWIG 2.0 and earlier versions didn't provide any mechanism to handle the Java director method exceptions in C++.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Converting Java exceptions into C++ exceptions can be done in two different ways using
|
Of course, should this exception be thrown, your C++ code must catch it and handle it before returning back to Java.
|
||||||
the <code>director:except</code> <a href="Customization.html#Customization_features">feature</a>.
|
The default generated code <b>does not</b> attempt to handle the C++ exception, but there is a simple way
|
||||||
In the simplest approach, a code block is attached to each director method to
|
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>.
|
||||||
handle the mapping of Java exceptions into C++ exceptions.
|
Consider the example shown earlier with a modification to the <tt>upcall_method</tt> Java method to throw a Java exception:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
%feature("director:except") MyClass::method(int x) {
|
class DirectorDerived extends DirectorBase {
|
||||||
jthrowable $error = jenv->ExceptionOccurred();
|
@Override
|
||||||
if ($error) {
|
public void upcall_method() {
|
||||||
jenv->ExceptionClear();
|
System.out.println("DirectorDerived.upcall_method() invoked.");
|
||||||
if (Swig::ExceptionMatches(jenv, $error, "java/lang/IndexOutOfBoundsException"))
|
throw new RuntimeException("There was a problem!");
|
||||||
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 MyClass {
|
|
||||||
/** Throws either a std::out_of_range or MyCppException on error */
|
|
||||||
void method(int x);
|
|
||||||
}
|
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
This approach allows a flexible mapping of Java exceptions thrown by director methods into
|
Now, by default, the JVM will abort when <tt>example.callup(director)</tt> is called as the C++
|
||||||
C++ exceptions expected by a C++ caller. There
|
<tt>Swig::DirectorException</tt> (storing the Java exception) is thrown and not handled by the <tt>callup</tt> method.
|
||||||
need not be any C++ <em>exception specifications</em> on the C++ method. The
|
Needless to say this is not very user friendly and so the recommendation is to add the following
|
||||||
utility function <code>Swig::ExceptionMatches</code>
|
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->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
|
and class <code>Swig::JavaExceptionMessage</code> are provided to simplify
|
||||||
writing code for wrappers that use the <code>director:except</code> feature. The
|
writing code for wrappers that use the <code>director:except</code> feature. The
|
||||||
function <code>Swig::ExceptionMatches</code> matches the type of 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
|
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
|
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
|
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
|
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
|
feature</a>.
|
||||||
should be used for the
|
The utility class <code>Swig::JavaExceptionMessage</code> is a holder
|
||||||
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
|
|
||||||
providing access to the message from the thrown Java exception.
|
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>,
|
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
|
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>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Using the above approach to
|
Using the first approach above to
|
||||||
write handlers for a large number of methods will require
|
write handlers for a large number of methods will require
|
||||||
repetitive duplication of the <code>director:except</code> feature code.
|
repetitive duplication of the <code>director:except</code> feature code
|
||||||
To mitigate this, an alternative approach is provided via typemaps in a
|
for each director method.
|
||||||
|
To mitigate this, a second approach is provided via typemaps in a
|
||||||
fashion analagous to
|
fashion analagous to
|
||||||
the <a href="Typemaps.html#throws_typemap">"throws" typemap.</a> The
|
the <a href="Typemaps.html#throws_typemap">"throws" typemap</a>.
|
||||||
"throws" typemap provides an approach to automatically map all the C++
|
The "throws" typemap provides a way to map all the C++
|
||||||
exceptions listed in a method's defined exceptions (either from
|
exceptions listed in a method's defined exceptions (either from
|
||||||
a C++ <em>exception specification</em> or a <code>%catches</code>
|
a C++ <em>exception specification</em> or a <code>%catches</code>
|
||||||
feature) into Java exceptions.
|
feature) into Java exceptions.
|
||||||
The "directorthrows" typemap provides the inverse mapping and should contain
|
The "directorthrows" typemap provides the inverse mapping and should contain
|
||||||
code to convert a suitably matching Java exception into a C++ exception.
|
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
|
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">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
|
|
@ -3913,7 +4059,7 @@ to the typemap's type, that is <code>std::out_of_range</code>:
|
||||||
<p>
|
<p>
|
||||||
The "directorthrows" typemap is then used in conjunction with the
|
The "directorthrows" typemap is then used in conjunction with the
|
||||||
<code>director:except</code> feature if the <code>$directorthrowshandlers</code> special variable
|
<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>
|
</p>
|
||||||
|
|
||||||
<div class="code">
|
<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") %{
|
%feature("director:except") %{
|
||||||
jthrowable $error = jenv->ExceptionOccurred();
|
jthrowable $error = jenv->ExceptionOccurred();
|
||||||
if ($error) {
|
if ($error) {
|
||||||
jenv->ExceptionClear();
|
|
||||||
$directorthrowshandlers
|
$directorthrowshandlers
|
||||||
Swig::DirectorException::raise(jenv, $error);
|
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>
|
</div>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
where <tt>Swig::DirectorException::raise</tt> is a helper method in the DirectorException class to throw a C++ exception (implemented in director.swg):
|
where <tt>Swig::DirectorException::raise</tt> is the helper method to throw a C++ <tt>Swig::DirectorException</tt>, see above.
|
||||||
</p>
|
The code generated from the <code>director:except</code> feature
|
||||||
|
has the <code>$directorthrowshandlers</code> special variable replaced with the code in
|
||||||
<div class="code">
|
the relevant "directorthrows" typemaps, for each and every exception defined for the method.
|
||||||
<pre>
|
The relevant exceptions can be defined either with a C++ exception
|
||||||
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
|
|
||||||
specification or <code>%catches</code> as described for the
|
specification or <code>%catches</code> as described for the
|
||||||
<a href="Typemaps.html#throws_typemap">"throws" typemap</a>.
|
<a href="Typemaps.html#throws_typemap">"throws" typemap</a>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Consider the following director method:
|
Let's try and put all this together by considering the following director method:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
...
|
struct X {
|
||||||
virtual void doSomething(int index) throw (std::out_of_range);
|
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>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -3970,11 +4114,9 @@ the resulting code generated in the director method after calling up to Java wil
|
||||||
<pre>
|
<pre>
|
||||||
jthrowable swigerror = jenv->ExceptionOccurred();
|
jthrowable swigerror = jenv->ExceptionOccurred();
|
||||||
if (swigerror) {
|
if (swigerror) {
|
||||||
jenv->ExceptionClear();
|
|
||||||
if (Swig::ExceptionMatches(jenv, swigerror, "java/lang/IndexOutOfBoundsException")) {
|
if (Swig::ExceptionMatches(jenv, swigerror, "java/lang/IndexOutOfBoundsException")) {
|
||||||
throw std::out_of_range(Swig::JavaExceptionMessage(jenv, swigerror).message());
|
throw std::out_of_range(Swig::JavaExceptionMessage(jenv, swigerror).message());
|
||||||
}
|
}
|
||||||
|
|
||||||
Swig::DirectorException::raise(jenv, swigerror);
|
Swig::DirectorException::raise(jenv, swigerror);
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
|
|
@ -3983,7 +4125,7 @@ if (swigerror) {
|
||||||
<p><em>
|
<p><em>
|
||||||
Note: Beware of using exception specifications as the SWIG director methods
|
Note: Beware of using exception specifications as the SWIG director methods
|
||||||
will be generated with the same exception specifications and if the
|
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.
|
to terminate your program. See the C++ standard for more details.
|
||||||
Using the %catches feature instead to define the handled exceptions does not suffer
|
Using the %catches feature instead to define the handled exceptions does not suffer
|
||||||
this potential fate.
|
this potential fate.
|
||||||
|
|
@ -3991,8 +4133,9 @@ this potential fate.
|
||||||
|
|
||||||
<p>Because the default code generation maps any unhandled Java exceptions to
|
<p>Because the default code generation maps any unhandled Java exceptions to
|
||||||
<code>Swig::DirectorException</code>, any director methods that have exception
|
<code>Swig::DirectorException</code>, any director methods that have exception
|
||||||
specifications may cause program termination. To simply ignore
|
specifications may cause program termination as this exception class won't be in the exception specifications list.
|
||||||
unexpected exceptions, the default handling can be changed with:
|
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>
|
</p>
|
||||||
|
|
||||||
<div class="code">
|
<div class="code">
|
||||||
|
|
@ -4000,8 +4143,8 @@ unexpected exceptions, the default handling can be changed with:
|
||||||
%feature("director:except") %{
|
%feature("director:except") %{
|
||||||
jthrowable $error = jenv->ExceptionOccurred();
|
jthrowable $error = jenv->ExceptionOccurred();
|
||||||
if ($error) {
|
if ($error) {
|
||||||
jenv->ExceptionClear();
|
|
||||||
$directorthrowshandlers
|
$directorthrowshandlers
|
||||||
|
jenv->ExceptionClear();
|
||||||
return $null; // exception is ignored
|
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
|
<p>Alternatively an exception compatible with the existing director
|
||||||
method exception specifications can be thrown. Assuming that all
|
method exception specifications can be thrown. Assuming that all
|
||||||
methods allow std::runtime_error to be thrown,
|
methods allow std::runtime_error to be thrown,
|
||||||
the <code>return $null;</code> could be changed to:
|
the <code>return $null</code> line above could be changed to:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="code">
|
<div class="code">
|
||||||
|
|
@ -4021,124 +4164,296 @@ the <code>return $null;</code> could be changed to:
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p>In more complex situations, a separate <code>director:except</code> feature
|
<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>
|
||||||
|
|
||||||
<p>Below is a complete example demonstrating the use
|
<p>This is all no doubt quite hard to follow without seeing a full example and some code.
|
||||||
of the "directorthrows" typemaps. In this example, a
|
Below is a complete example demonstrating the use
|
||||||
generic "directorthrows" typemap is appropriate for all three exceptions - all
|
of most of the exception customizations one can use, that is,
|
||||||
take single string constructors. If the exceptions had different constructors,
|
"directorthrows" and "throws" typemaps, %exception and %catches.
|
||||||
it would be necessary to have separate typemaps for each exception type.
|
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">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
%module(directors="1") example
|
%module(directors="1") example
|
||||||
|
|
||||||
%{
|
%{
|
||||||
#include <string>
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <iostream>
|
||||||
%}
|
%}
|
||||||
|
|
||||||
// Define exceptions in header section using std::runtime_error
|
// Generic catch handler for all wrapped methods
|
||||||
%define DEFINE_EXCEPTION(NAME)
|
%exception %{
|
||||||
%{
|
try {
|
||||||
namespace MyNS {
|
$action
|
||||||
struct NAME : public std::runtime_error { NAME(const std::string &what) : runtime_error(what) {} };
|
} catch (const std::exception &e) {
|
||||||
|
std::cout << "Generic std::exception catch handler" << std::endl;
|
||||||
|
jclass clazz = jenv->FindClass("java/lang/RuntimeException");
|
||||||
|
jenv->ThrowNew(clazz, e.what());
|
||||||
|
return $null;
|
||||||
}
|
}
|
||||||
%}
|
%}
|
||||||
%enddef
|
|
||||||
|
|
||||||
// Expose C++ exceptions as Java Exceptions by changing the Java base class and providing a getMessage()
|
// Expose C++ exception as a Java Exception by changing the Java base class and providing a getMessage()
|
||||||
%define DECLARE_EXCEPTION(NAME)
|
%typemap(javabase) MyNS::MyException "java.lang.RuntimeException";
|
||||||
%typemap(javabase) MyNS::NAME "java.lang.Exception";
|
%rename(getMessage) MyNS::MyException::whatsup;
|
||||||
%rename(getMessage) MyNS::NAME::what;
|
|
||||||
|
%inline %{
|
||||||
namespace MyNS {
|
namespace MyNS {
|
||||||
struct NAME {
|
class MyException {
|
||||||
NAME(const std::string& what);
|
std::string msg;
|
||||||
const char * what();
|
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)
|
%typemap(directorthrows) MyNS::MyException %{
|
||||||
DECLARE_EXCEPTION(ExceptionB)
|
if (Swig::ExceptionMatches(jenv, $error, "$packagepath/MyException")) {
|
||||||
DECLARE_EXCEPTION(Unexpected)
|
std::cout << "$1_type exception matched (directorthrows typemap)" << 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 << "$1_type caught (throws typemap)" << std::endl;
|
||||||
|
jclass excep = jenv->FindClass("MyException");
|
||||||
|
if (excep) {
|
||||||
|
std::cout << "$1_type class found (throws typemap)" << std::endl;
|
||||||
|
jenv->ThrowNew(excep, $1.whatsup());
|
||||||
|
}
|
||||||
|
return $null;
|
||||||
|
%}
|
||||||
|
|
||||||
%inline {
|
// 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->ExceptionOccurred();
|
||||||
|
if ($error) {
|
||||||
|
std::cout << "Upcall finished, an exception was thrown in Java" << std::endl;
|
||||||
|
$directorthrowshandlers
|
||||||
|
std::cout << "Upcall finished, no exception conversion, throwing DirectorException" << std::endl;
|
||||||
|
Swig::DirectorException::raise(jenv, $error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
%inline %{
|
||||||
class MyClass {
|
class MyClass {
|
||||||
public:
|
public:
|
||||||
virtual void meth1(int x) throw(MyNS::ExceptionA, MyNS::ExceptionB) = 0;
|
/** Throws either a std::out_of_range or MyException on error */
|
||||||
virtual void meth2() = 0; /* throws MyNS::ExceptionA, MyNS::ExceptionB, MyNS::Unexpected */
|
virtual void dirmethod(int x) {
|
||||||
virtual void meth3(float x) throw(MyNS::Unexpected) = 0;
|
if (x <= 0)
|
||||||
virtual ~MyClass() {}
|
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& c, int x) {
|
||||||
|
return c.dirmethod(x);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
%}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
In this case the three different "directorthrows" typemaps will be used
|
The generated code for the <tt>call_dirmethod</tt> wrapper contains the various exception handlers.
|
||||||
to generate the three different exception handlers for
|
The outer exception handler is from the <tt>%exception</tt> directive and the others
|
||||||
<code>meth1</code>, <code>meth2</code> and <code>meth3</code>. The generated
|
are from the "throws" typemaps.
|
||||||
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:
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
%javaexception("Exception") MyClass::myMethod %{
|
SWIGEXPORT void JNICALL Java_exampleJNI_MyClass_1call_1dirmethod(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2) {
|
||||||
|
...
|
||||||
try {
|
try {
|
||||||
$action
|
try {
|
||||||
} catch (Swig::DirectorException &e) {
|
MyClass::call_dirmethod(*arg1,arg2);
|
||||||
// raise/throw the Java exception that originally caused the DirectorException
|
} catch(MyNS::MyException &_e) {
|
||||||
e.raiseJavaException(jenv);
|
std::cout << "MyNS::MyException caught (throws typemap)" << std::endl;
|
||||||
return $null;
|
jclass excep = jenv->FindClass("MyException");
|
||||||
|
if (excep) {
|
||||||
|
std::cout << "MyNS::MyException class found (throws typemap)" << std::endl;
|
||||||
|
jenv->ThrowNew(excep, (&_e)->whatsup());
|
||||||
|
}
|
||||||
|
return ;
|
||||||
|
|
||||||
|
} catch(Swig::DirectorException &_e) {
|
||||||
|
(&_e)->throwException(jenv);
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
std::cout << "Generic std::exception catch handler" << std::endl;
|
||||||
|
jclass clazz = jenv->FindClass("java/lang/RuntimeException");
|
||||||
|
jenv->ThrowNew(clazz, e.what());
|
||||||
|
return ;
|
||||||
}
|
}
|
||||||
%}
|
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
See the <a href="#Java_exception_handling">Exception handling with %exception and %javaexception</a>
|
The director method calling up to Java contains the exception handling code from the "directorthrows" typemaps and <tt>director:except</tt> feature.
|
||||||
section for more on converting C++ exceptions to Java exceptions.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
void SwigDirector_MyClass::dirmethod(int x) {
|
||||||
|
... [call up to Java using CallStaticVoidMethod]
|
||||||
|
jthrowable swigerror = jenv->ExceptionOccurred();
|
||||||
|
if (swigerror) {
|
||||||
|
std::cout << "Upcall finished, an exception was thrown in Java" << std::endl;
|
||||||
|
|
||||||
|
if (Swig::ExceptionMatches(jenv, swigerror, "MyException")) {
|
||||||
|
std::cout << "MyNS::MyException exception matched (directorthrows typemap)" << std::endl;
|
||||||
|
throw MyNS::MyException(Swig::JavaExceptionMessage(jenv, swigerror).message());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "Upcall finished, no exception conversion, throwing DirectorException" << 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 < 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>
|
<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
|
// Ensure that the GC doesn't collect any Element set from Java
|
||||||
// as the underlying C++ class stores a shallow copy
|
// as the underlying C++ class stores a shallow copy
|
||||||
private Element elementReference;
|
private Element elementReference;
|
||||||
private long getCPtrAndAddReference(Element element) {
|
|
||||||
elementReference = element;
|
|
||||||
return Element.getCPtr(element);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setElement(Element e) {
|
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>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The following typemaps will generate the desired code.
|
The following typemaps can be used to generate this 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.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
%typemap(javain) Element *e "getCPtrAndAddReference($javainput)"
|
|
||||||
|
|
||||||
%typemap(javacode) Container %{
|
%typemap(javacode) Container %{
|
||||||
// Ensure that the GC doesn't collect any element set from Java
|
// Ensure that the GC doesn't collect any element set from Java
|
||||||
// as the underlying C++ class stores a shallow copy
|
// as the underlying C++ class stores a shallow copy
|
||||||
private Element elementReference;
|
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>
|
</pre>
|
||||||
</div>
|
</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>
|
<H3><a name="Java_date_marshalling">25.10.13 Date marshalling using the javain typemap and associated attributes</a></H3>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="#Library_shared_ptr_basics">shared_ptr basics</a>
|
<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_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_templates">shared_ptr and templates</a>
|
||||||
<li><a href="#Library_shared_ptr_directors">shared_ptr and directors</a>
|
<li><a href="#Library_shared_ptr_directors">shared_ptr and directors</a>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
@ -502,6 +503,7 @@ you should consider using a special array object rather than a bare pointer.
|
||||||
<p>
|
<p>
|
||||||
<b>Note:</b> <tt>%array_functions()</tt> and <tt>%array_class()</tt> should not be
|
<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>.
|
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>
|
</p>
|
||||||
|
|
||||||
<H3><a name="Library_nn6">9.2.3 cmalloc.i</a></H3>
|
<H3><a name="Library_nn6">9.2.3 cmalloc.i</a></H3>
|
||||||
|
|
@ -1921,7 +1923,30 @@ Adding the missing <tt>%shared_ptr</tt> macros will fix this:
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</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<GrandParent> num);
|
||||||
|
int age(GrandParent& 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>
|
<p>
|
||||||
The <tt>%shared_ptr</tt> macro should be used for all the required instantiations
|
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>
|
</pre>
|
||||||
</div>
|
</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>
|
<p>
|
||||||
There is somewhat limited support for <tt>%shared_ptr</tt> and the director feature
|
The languages that support shared_ptr also have support for using shared_ptr with directors.
|
||||||
and the degrees of success varies among the different target languages.
|
|
||||||
Please help to improve this support by providing patches with improvements.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6521,14 +6521,16 @@ string that cannot be completely decoded as UTF-8:
|
||||||
<div class="code"><pre>
|
<div class="code"><pre>
|
||||||
%module example
|
%module example
|
||||||
|
|
||||||
%include <std_string.i>
|
|
||||||
|
|
||||||
%inline %{
|
%inline %{
|
||||||
|
|
||||||
const char * non_utf8_c_str(void) {
|
const char * non_utf8_c_str(void) {
|
||||||
return "h\xe9llo w\xc3\xb6rld";
|
return "h\xe9llo w\xc3\xb6rld";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void instring(const char *s) {
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
%}
|
%}
|
||||||
</pre></div>
|
</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>.
|
<a href="https://www.python.org/dev/peps/pep-0383/">PEP 383</a>.
|
||||||
</p>
|
</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>
|
||||||
|
>>> example.instring('h\xe9llo')
|
||||||
|
>>> example.instring('h\udce9llo')
|
||||||
|
Traceback (most recent call last):
|
||||||
|
File "<stdin>", line 1, in <module>
|
||||||
|
TypeError: in method 'instring', argument 1 of type 'char const *'
|
||||||
|
</pre></div>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
In some cases, users may wish to instead handle all byte strings as bytes
|
In some cases, users may wish to instead handle all byte strings as bytes
|
||||||
objects in Python 3. This can be accomplished by adding
|
objects in Python 3. This can be accomplished by adding
|
||||||
|
|
|
||||||
|
|
@ -3343,7 +3343,7 @@ SWIG_From_float(float)</td>
|
||||||
|
|
||||||
|
|
||||||
<p>Here, while the Ruby versions return the value directly, the SWIG
|
<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">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
|
|
|
||||||
|
|
@ -163,6 +163,32 @@ can be obtained by typing <tt>swig -help</tt> or <tt>swig
|
||||||
|
|
||||||
</pre></div>
|
</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>
|
<H3><a name="SWIG_nn3">5.1.1 Input format</a></H3>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2177,7 +2203,7 @@ in the C++ chapter for further details.
|
||||||
<p>
|
<p>
|
||||||
Occasionally, a C library may include functions that expect to receive
|
Occasionally, a C library may include functions that expect to receive
|
||||||
pointers to functions--possibly to serve as callbacks. SWIG
|
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,
|
functions are defined in C and not in the target language. For example,
|
||||||
consider a function like this:
|
consider a function like this:
|
||||||
</p>
|
</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
|
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.
|
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
|
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>
|
</p>
|
||||||
|
|
||||||
<H2><a name="SWIG_nn31">5.5 Structures and unions</a></H2>
|
<H2><a name="SWIG_nn31">5.5 Structures and unions</a></H2>
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,11 @@
|
||||||
<li><a href="#SWIGPlus_nn35">Using declarations and inheritance</a>
|
<li><a href="#SWIGPlus_nn35">Using declarations and inheritance</a>
|
||||||
<li><a href="#SWIGPlus_nested_classes">Nested classes</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_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>
|
<li><a href="#SWIGPlus_nn42">Where to go for more information</a>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -80,7 +85,10 @@
|
||||||
|
|
||||||
|
|
||||||
<p>
|
<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
|
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
|
how SWIG wraps ANSI C. Support for C++ builds upon ANSI C
|
||||||
wrapping and that material will be useful in understanding this chapter.
|
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>
|
||||||
|
|
||||||
<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>
|
</p>
|
||||||
|
|
||||||
<div class="code">
|
<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.
|
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.
|
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.
|
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.
|
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.
|
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 "...".
|
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.
|
of your project.
|
||||||
</p>
|
</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->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, &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>
|
<p>
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@
|
||||||
<li><a href="#Typemaps_nn35">"memberin" typemap</a>
|
<li><a href="#Typemaps_nn35">"memberin" typemap</a>
|
||||||
<li><a href="#Typemaps_nn36">"varin" typemap</a>
|
<li><a href="#Typemaps_nn36">"varin" typemap</a>
|
||||||
<li><a href="#Typemaps_nn37">"varout" 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>
|
</ul>
|
||||||
<li><a href="#Typemaps_nn39">Some typemap examples</a>
|
<li><a href="#Typemaps_nn39">Some typemap examples</a>
|
||||||
<ul>
|
<ul>
|
||||||
|
|
@ -89,6 +89,9 @@
|
||||||
<li><a href="#Typemaps_runtime_type_checker_usage">Usage</a>
|
<li><a href="#Typemaps_runtime_type_checker_usage">Usage</a>
|
||||||
</ul>
|
</ul>
|
||||||
<li><a href="#Typemaps_overloading">Typemaps and overloading</a>
|
<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_nn48">More about %apply and %clear</a>
|
||||||
<li><a href="#Typemaps_nn47">Passing data between typemaps</a>
|
<li><a href="#Typemaps_nn47">Passing data between typemaps</a>
|
||||||
<li><a href="#Typemaps_nn52">C++ "this" pointer</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.
|
language when reading a C/C++ global variable. This is implementation specific.
|
||||||
</p>
|
</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>
|
<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.
|
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.
|
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.
|
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);
|
PyErr_SetString(PyExc_RuntimeError, $1);
|
||||||
SWIG_fail;
|
SWIG_fail;
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
// Either an exception specification on the method
|
||||||
void bar() throw (const char *);
|
void bar() throw (const char *);
|
||||||
|
|
||||||
|
// Or a %catches feature attached to the method
|
||||||
|
%catches(const char *) bar();
|
||||||
|
void bar();
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
As can be seen from the generated code below, SWIG generates an exception handler
|
As can be seen from the resulting generated code below, SWIG generates an exception handler
|
||||||
with the catch block comprising the "throws" typemap content.
|
when wrapping the <tt>bar</tt> function with the catch block comprising the "throws" typemap content.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="code">
|
<div class="code">
|
||||||
|
|
@ -2912,8 +2921,7 @@ with the catch block comprising the "throws" typemap content.
|
||||||
...
|
...
|
||||||
try {
|
try {
|
||||||
bar();
|
bar();
|
||||||
}
|
} catch(char const *_e) {
|
||||||
catch(char const *_e) {
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, _e);
|
PyErr_SetString(PyExc_RuntimeError, _e);
|
||||||
SWIG_fail;
|
SWIG_fail;
|
||||||
}
|
}
|
||||||
|
|
@ -2922,8 +2930,8 @@ catch(char const *_e) {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p>
|
<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.
|
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.
|
||||||
For a neat way to handle these, see the <a href="Customization.html#Customization_exception">Exception handling with %exception</a> section.
|
Please also see the <a href="Customization.html#Customization_exception">Exception handling with %exception</a> section for another way to handle exceptions.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<H2><a name="Typemaps_nn39">11.6 Some typemap examples</a></H2>
|
<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">
|
<div class="shell">
|
||||||
<pre>
|
<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>
|
</pre>
|
||||||
</div>
|
</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.
|
Subsequent "in" typemaps would then perform more extensive type-checking.
|
||||||
</li>
|
</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>
|
</li>
|
||||||
</ul>
|
</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 &c); // equivalent: void m(X *c);
|
||||||
|
void m(X &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 &) effectively ignored,
|
||||||
|
example.i:5: Warning 509: as it is shadowed by m(X const &).
|
||||||
|
example.i:7: Warning 509: Overloaded method m(X *) effectively ignored,
|
||||||
|
example.i:5: Warning 509: as it is shadowed by m(X const &).
|
||||||
|
</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 &) ignored,
|
||||||
|
example.i:5: Warning 516: using m(X const &) instead.
|
||||||
|
example.i:7: Warning 516: Overloaded method m(X *) ignored,
|
||||||
|
example.i:5: Warning 516: using m(X const &) 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 &</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 & "..."
|
||||||
|
%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 &</tt>, <tt>X &</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<X> " ... "
|
||||||
|
|
||||||
|
void m(X &r); // equivalent: void m(X *r);
|
||||||
|
void m(MySmartPtr<X> 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>
|
<H2><a name="Typemaps_nn48">11.14 More about %apply and %clear</a></H2>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -529,8 +529,11 @@ like this:
|
||||||
SWIG_fail;
|
SWIG_fail;
|
||||||
}
|
}
|
||||||
pystr = PyUnicode_AsUTF8String(pyobj);
|
pystr = PyUnicode_AsUTF8String(pyobj);
|
||||||
|
if (!pystr) {
|
||||||
|
SWIG_fail;
|
||||||
|
}
|
||||||
str = strdup(PyBytes_AsString(pystr));
|
str = strdup(PyBytes_AsString(pystr));
|
||||||
Py_XDECREF(pystr);
|
Py_DECREF(pystr);
|
||||||
%#else
|
%#else
|
||||||
if (!PyString_Check(pyobj)) {
|
if (!PyString_Check(pyobj)) {
|
||||||
PyErr_SetString(PyExc_ValueError, "Expected a string");
|
PyErr_SetString(PyExc_ValueError, "Expected a string");
|
||||||
|
|
|
||||||
|
|
@ -334,8 +334,8 @@ else
|
||||||
SWIGOPTPY3 = -py3
|
SWIGOPTPY3 = -py3
|
||||||
endif
|
endif
|
||||||
|
|
||||||
PEP8 = @PEP8@
|
PYCODESTYLE = @PYCODESTYLE@
|
||||||
PEP8_FLAGS = --ignore=E402,E501,E30,W291,W391
|
PYCODESTYLE_FLAGS = --ignore=E402,E501,E30,W291,W391
|
||||||
|
|
||||||
# ----------------------------------------------------------------
|
# ----------------------------------------------------------------
|
||||||
# Build a C dynamically loadable module
|
# Build a C dynamically loadable module
|
||||||
|
|
@ -386,11 +386,11 @@ else
|
||||||
PYSCRIPT = $(RUNME)3.py
|
PYSCRIPT = $(RUNME)3.py
|
||||||
endif
|
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)
|
python_run: $(PYSCRIPT)
|
||||||
ifneq (,$(PEP8))
|
ifneq (,$(PYCODESTYLE))
|
||||||
$(COMPILETOOL) $(PEP8) $(PEP8_FLAGS) $(PYSCRIPT)
|
$(COMPILETOOL) $(PYCODESTYLE) $(PYCODESTYLE_FLAGS) $(PYSCRIPT)
|
||||||
endif
|
endif
|
||||||
env PYTHONPATH=$$PWD $(RUNTOOL) $(PYTHON) $(PYSCRIPT) $(RUNPIPE)
|
env PYTHONPATH=$$PWD $(RUNTOOL) $(PYTHON) $(PYSCRIPT) $(RUNPIPE)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ constants2
|
||||||
extend
|
extend
|
||||||
funcptr
|
funcptr
|
||||||
import
|
import
|
||||||
java
|
|
||||||
multimap
|
multimap
|
||||||
multiple_inheritance
|
multiple_inheritance
|
||||||
pointer
|
pointer
|
||||||
|
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
%module example
|
|
||||||
|
|
||||||
%include <cni.i>
|
|
||||||
|
|
||||||
%{
|
|
||||||
#include "Example.h"
|
|
||||||
%}
|
|
||||||
|
|
||||||
|
|
||||||
%include Example.h
|
|
||||||
|
|
@ -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()
|
|
||||||
|
|
@ -14,7 +14,6 @@ functor
|
||||||
import
|
import
|
||||||
import_template
|
import_template
|
||||||
import_packages
|
import_packages
|
||||||
java
|
|
||||||
#libffi
|
#libffi
|
||||||
multimap
|
multimap
|
||||||
operator
|
operator
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import_packages_subdirs = \
|
||||||
relativeimport2 \
|
relativeimport2 \
|
||||||
relativeimport3 \
|
relativeimport3 \
|
||||||
split_modules \
|
split_modules \
|
||||||
namespace_pkg
|
namespace_pkg \
|
||||||
|
|
||||||
|
|
||||||
check: build
|
check: build
|
||||||
|
|
@ -21,19 +21,19 @@ check: build
|
||||||
mkdir -p `dirname $$file`; \
|
mkdir -p `dirname $$file`; \
|
||||||
cp "${SRCDIR}$$file" "$$file" || exit 1; \
|
cp "${SRCDIR}$$file" "$$file" || exit 1; \
|
||||||
done; \
|
done; \
|
||||||
fi; \
|
fi
|
||||||
for s in $(import_packages_subdirs); do \
|
for s in $(import_packages_subdirs); do \
|
||||||
(cd $$s && $(MAKE) check); \
|
(cd $$s && $(MAKE) check) || exit 1; \
|
||||||
done
|
done
|
||||||
|
|
||||||
build:
|
build:
|
||||||
for s in $(import_packages_subdirs); do \
|
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
|
done
|
||||||
|
|
||||||
static:
|
static:
|
||||||
for s in $(import_packages_subdirs); do \
|
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
|
done
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
|
|
@ -42,7 +42,7 @@ clean:
|
||||||
for file in `cd $(SRCDIR) && find . -type f -name "*.py"`; do \
|
for file in `cd $(SRCDIR) && find . -type f -name "*.py"`; do \
|
||||||
rm -f "$$file" || exit 1; \
|
rm -f "$$file" || exit 1; \
|
||||||
done; \
|
done; \
|
||||||
fi; \
|
fi
|
||||||
for s in $(import_packages_subdirs); do \
|
for s in $(import_packages_subdirs); do \
|
||||||
(cd $$s && $(MAKE) clean); \
|
(cd $$s && $(MAKE) clean) || exit 1; \
|
||||||
done
|
done
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,10 @@ import os.path
|
||||||
testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
|
testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
|
||||||
print "Testing " + testname + " - %module(package=...) + python 'import' in __init__.py"
|
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):
|
if sys.version_info < (3, 0):
|
||||||
import py2.pkg2
|
import py2.pkg2
|
||||||
print " Finished importing py2.pkg2"
|
print " Finished importing py2.pkg2"
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,10 @@ import os.path
|
||||||
testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
|
testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
|
||||||
print "Testing " + testname + " - %module(package=...) + python 'import' in __init__.py"
|
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):
|
if sys.version_info < (3, 0):
|
||||||
import py2.pkg2
|
import py2.pkg2
|
||||||
print " Finished importing py2.pkg2"
|
print " Finished importing py2.pkg2"
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,10 @@ import os.path
|
||||||
testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
|
testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
|
||||||
print "Testing " + testname + " - %module(package=...) + python 'import' in __init__.py"
|
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):
|
if sys.version_info < (3, 0):
|
||||||
import py2.pkg2
|
import py2.pkg2
|
||||||
print " Finished importing py2.pkg2"
|
print " Finished importing py2.pkg2"
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,10 @@ import os.path
|
||||||
testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
|
testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
|
||||||
print "Testing " + testname + " - %module(package=...) with -relativeimport"
|
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):
|
if sys.version_info < (3, 0):
|
||||||
import py2.pkg2.bar
|
import py2.pkg2.bar
|
||||||
print " Finished importing py2.pkg2.bar"
|
print " Finished importing py2.pkg2.bar"
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,10 @@ import os.path
|
||||||
testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
|
testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
|
||||||
print "Testing " + testname + " - %module(package=...) + python 'import' in __init__.py"
|
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):
|
if sys.version_info < (3, 0):
|
||||||
import py2.pkg2.bar
|
import py2.pkg2.bar
|
||||||
print " Finished importing py2.pkg2.bar"
|
print " Finished importing py2.pkg2.bar"
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,10 @@ import os.path
|
||||||
testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
|
testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
|
||||||
print "Testing " + testname + " - %module(package=...) with -relativeimport"
|
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):
|
if sys.version_info < (3, 0):
|
||||||
import py2.pkg2.bar
|
import py2.pkg2.bar
|
||||||
print " Finished importing py2.pkg2.bar"
|
print " Finished importing py2.pkg2.bar"
|
||||||
|
|
|
||||||
|
|
@ -6,21 +6,21 @@ subdirs = vanilla vanilla_split
|
||||||
|
|
||||||
check: build
|
check: build
|
||||||
for s in $(subdirs); do \
|
for s in $(subdirs); do \
|
||||||
(cd $$s && $(MAKE) check); \
|
(cd $$s && $(MAKE) check) || exit 1; \
|
||||||
done
|
done
|
||||||
|
|
||||||
build:
|
build:
|
||||||
for s in $(subdirs); do \
|
for s in $(subdirs); do \
|
||||||
(cd $$s && $(MAKE) SWIGOPT='$(SWIGOPT)' LIBS='$(LIBS)' build); \
|
(cd $$s && $(MAKE) SWIGOPT='$(SWIGOPT)' LIBS='$(LIBS)' build) || exit 1; \
|
||||||
done
|
done
|
||||||
|
|
||||||
static:
|
static:
|
||||||
for s in $(subdirs); do \
|
for s in $(subdirs); do \
|
||||||
(cd $$s && $(MAKE) SWIGOPT='$(SWIGOPT)' LIBS='$(LIBS)' static); \
|
(cd $$s && $(MAKE) SWIGOPT='$(SWIGOPT)' LIBS='$(LIBS)' static) || exit 1; \
|
||||||
done
|
done
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' python_clean
|
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' python_clean
|
||||||
for s in $(subdirs); do \
|
for s in $(subdirs); do \
|
||||||
(cd $$s && $(MAKE) clean); \
|
(cd $$s && $(MAKE) clean) || exit 1; \
|
||||||
done
|
done
|
||||||
|
|
|
||||||
|
|
@ -19,4 +19,6 @@ static:
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' TARGET='foo' python_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
|
||||||
|
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
%module example
|
|
||||||
%include <cni.i>
|
|
||||||
|
|
||||||
%{
|
|
||||||
#include "Example.h"
|
|
||||||
%}
|
|
||||||
|
|
||||||
|
|
||||||
%include Example.h
|
|
||||||
|
|
||||||
%extend Example {
|
|
||||||
~Example() {}
|
|
||||||
}
|
|
||||||
|
|
@ -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()
|
|
||||||
|
|
@ -39,7 +39,11 @@ extern int gcd(int x, int y);
|
||||||
%#if PY_VERSION_HEX >= 0x03000000
|
%#if PY_VERSION_HEX >= 0x03000000
|
||||||
{
|
{
|
||||||
PyObject *utf8str = PyUnicode_AsUTF8String(s);
|
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);
|
$2[i] = strdup(cstr);
|
||||||
Py_DECREF(utf8str);
|
Py_DECREF(utf8str);
|
||||||
}
|
}
|
||||||
|
|
@ -72,6 +76,9 @@ extern int gcdmain(int argc, char *argv[]);
|
||||||
SWIG_fail;
|
SWIG_fail;
|
||||||
}
|
}
|
||||||
utf8str = PyUnicode_AsUTF8String($input);
|
utf8str = PyUnicode_AsUTF8String($input);
|
||||||
|
if (!utf8str) {
|
||||||
|
SWIG_fail;
|
||||||
|
}
|
||||||
PyBytes_AsStringAndSize(utf8str, &cstr, &len);
|
PyBytes_AsStringAndSize(utf8str, &cstr, &len);
|
||||||
$1 = strncpy((char *)malloc(len+1), cstr, (size_t)len);
|
$1 = strncpy((char *)malloc(len+1), cstr, (size_t)len);
|
||||||
$2 = (int)len;
|
$2 = (int)len;
|
||||||
|
|
@ -105,6 +112,9 @@ extern int count(char *bytes, int len, char c);
|
||||||
char *cstr;
|
char *cstr;
|
||||||
Py_ssize_t len;
|
Py_ssize_t len;
|
||||||
PyObject *utf8str = PyUnicode_AsUTF8String($input);
|
PyObject *utf8str = PyUnicode_AsUTF8String($input);
|
||||||
|
if (!utf8str) {
|
||||||
|
SWIG_fail;
|
||||||
|
}
|
||||||
PyBytes_AsStringAndSize(utf8str, &cstr, &len);
|
PyBytes_AsStringAndSize(utf8str, &cstr, &len);
|
||||||
$1 = strncpy((char *)malloc(len+1), cstr, (size_t)len);
|
$1 = strncpy((char *)malloc(len+1), cstr, (size_t)len);
|
||||||
$2 = (int)len;
|
$2 = (int)len;
|
||||||
|
|
|
||||||
|
|
@ -52,14 +52,14 @@ print " Tring to set 'path'"
|
||||||
try:
|
try:
|
||||||
example.cvar.path = "Whoa!"
|
example.cvar.path = "Whoa!"
|
||||||
print "Hey, what's going on?!?! This shouldn't work"
|
print "Hey, what's going on?!?! This shouldn't work"
|
||||||
except:
|
except Exception:
|
||||||
print "Good."
|
print "Good."
|
||||||
|
|
||||||
print " Trying to set 'status'"
|
print " Trying to set 'status'"
|
||||||
try:
|
try:
|
||||||
example.cvar.status = 0
|
example.cvar.status = 0
|
||||||
print "Hey, what's going on?!?! This shouldn't work"
|
print "Hey, what's going on?!?! This shouldn't work"
|
||||||
except:
|
except Exception:
|
||||||
print "Good."
|
print "Good."
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ functor
|
||||||
hashargs
|
hashargs
|
||||||
import
|
import
|
||||||
import_template
|
import_template
|
||||||
java
|
|
||||||
mark_function
|
mark_function
|
||||||
multimap
|
multimap
|
||||||
operator
|
operator
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,11 @@ GC.start
|
||||||
# C++ object
|
# C++ object
|
||||||
ok = false
|
ok = false
|
||||||
begin
|
begin
|
||||||
|
# Let's stress the GC a bit, a single pass might not be enough.
|
||||||
|
10.times {
|
||||||
|
GC.start
|
||||||
puts tiger2.get_name
|
puts tiger2.get_name
|
||||||
|
}
|
||||||
rescue ObjectPreviouslyDeleted => error
|
rescue ObjectPreviouslyDeleted => error
|
||||||
ok = true
|
ok = true
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
%module example
|
|
||||||
%include <cni.i>
|
|
||||||
|
|
||||||
%{
|
|
||||||
#include "Example.h"
|
|
||||||
%}
|
|
||||||
|
|
||||||
|
|
||||||
%include Example.h
|
|
||||||
|
|
@ -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()
|
|
||||||
|
|
||||||
|
|
@ -5,7 +5,6 @@ contract
|
||||||
enum
|
enum
|
||||||
funcptr
|
funcptr
|
||||||
import
|
import
|
||||||
java
|
|
||||||
multimap
|
multimap
|
||||||
operator
|
operator
|
||||||
pointer
|
pointer
|
||||||
|
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
%module example
|
|
||||||
%include <cni.i>
|
|
||||||
|
|
||||||
%{
|
|
||||||
#include "Example.h"
|
|
||||||
%}
|
|
||||||
|
|
||||||
%include Example.h
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
%module class_scope_namespace
|
%module class_scope_namespace
|
||||||
|
|
||||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) H::HH;
|
%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 %{
|
%inline %{
|
||||||
struct A;
|
struct A;
|
||||||
|
|
@ -107,12 +107,12 @@ void hhh(H::HH) {}
|
||||||
|
|
||||||
namespace Space8 {
|
namespace Space8 {
|
||||||
struct II;
|
struct II;
|
||||||
struct I {
|
struct I_ {
|
||||||
struct II {
|
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;
|
struct J;
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,6 @@ CPP_TEST_BROKEN += \
|
||||||
extend_variable \
|
extend_variable \
|
||||||
li_boost_shared_ptr_template \
|
li_boost_shared_ptr_template \
|
||||||
nested_private \
|
nested_private \
|
||||||
overload_complicated \
|
|
||||||
rename_camel \
|
rename_camel \
|
||||||
template_default_pointer \
|
template_default_pointer \
|
||||||
template_private_assignment \
|
template_private_assignment \
|
||||||
|
|
@ -165,6 +164,7 @@ CPP_TEST_CASES += \
|
||||||
cpp_typedef \
|
cpp_typedef \
|
||||||
curiously_recurring_template_pattern \
|
curiously_recurring_template_pattern \
|
||||||
default_args \
|
default_args \
|
||||||
|
default_arg_expressions \
|
||||||
default_arg_values \
|
default_arg_values \
|
||||||
default_constructor \
|
default_constructor \
|
||||||
defvalue_constructor \
|
defvalue_constructor \
|
||||||
|
|
@ -182,6 +182,7 @@ CPP_TEST_CASES += \
|
||||||
director_detect \
|
director_detect \
|
||||||
director_enum \
|
director_enum \
|
||||||
director_exception \
|
director_exception \
|
||||||
|
director_exception_catches \
|
||||||
director_extend \
|
director_extend \
|
||||||
director_finalizer \
|
director_finalizer \
|
||||||
director_frob \
|
director_frob \
|
||||||
|
|
@ -193,6 +194,7 @@ CPP_TEST_CASES += \
|
||||||
director_nspace_director_name_collision \
|
director_nspace_director_name_collision \
|
||||||
director_overload \
|
director_overload \
|
||||||
director_overload2 \
|
director_overload2 \
|
||||||
|
director_ownership \
|
||||||
director_pass_by_value \
|
director_pass_by_value \
|
||||||
director_primitives \
|
director_primitives \
|
||||||
director_property \
|
director_property \
|
||||||
|
|
@ -264,9 +266,10 @@ CPP_TEST_CASES += \
|
||||||
li_attribute \
|
li_attribute \
|
||||||
li_attribute_template \
|
li_attribute_template \
|
||||||
li_boost_shared_ptr \
|
li_boost_shared_ptr \
|
||||||
li_boost_shared_ptr_bits \
|
|
||||||
li_boost_shared_ptr_template \
|
|
||||||
li_boost_shared_ptr_attribute \
|
li_boost_shared_ptr_attribute \
|
||||||
|
li_boost_shared_ptr_bits \
|
||||||
|
li_boost_shared_ptr_director \
|
||||||
|
li_boost_shared_ptr_template \
|
||||||
li_carrays_cpp \
|
li_carrays_cpp \
|
||||||
li_cdata_cpp \
|
li_cdata_cpp \
|
||||||
li_cpointer_cpp \
|
li_cpointer_cpp \
|
||||||
|
|
@ -317,6 +320,7 @@ CPP_TEST_CASES += \
|
||||||
nested_template_base \
|
nested_template_base \
|
||||||
nested_workaround \
|
nested_workaround \
|
||||||
newobject1 \
|
newobject1 \
|
||||||
|
newobject3 \
|
||||||
null_pointer \
|
null_pointer \
|
||||||
operator_overload \
|
operator_overload \
|
||||||
operator_overload_break \
|
operator_overload_break \
|
||||||
|
|
@ -325,6 +329,7 @@ CPP_TEST_CASES += \
|
||||||
ordering \
|
ordering \
|
||||||
overload_arrays \
|
overload_arrays \
|
||||||
overload_bool \
|
overload_bool \
|
||||||
|
overload_complicated \
|
||||||
overload_copy \
|
overload_copy \
|
||||||
overload_extend \
|
overload_extend \
|
||||||
overload_method \
|
overload_method \
|
||||||
|
|
@ -405,6 +410,7 @@ CPP_TEST_CASES += \
|
||||||
template_basic \
|
template_basic \
|
||||||
template_base_template \
|
template_base_template \
|
||||||
template_classes \
|
template_classes \
|
||||||
|
template_class_reuse_name \
|
||||||
template_const_ref \
|
template_const_ref \
|
||||||
template_construct \
|
template_construct \
|
||||||
template_templated_constructors \
|
template_templated_constructors \
|
||||||
|
|
@ -486,6 +492,7 @@ CPP_TEST_CASES += \
|
||||||
throw_exception \
|
throw_exception \
|
||||||
typedef_array_member \
|
typedef_array_member \
|
||||||
typedef_class \
|
typedef_class \
|
||||||
|
typedef_classforward_same_name \
|
||||||
typedef_funcptr \
|
typedef_funcptr \
|
||||||
typedef_inherit \
|
typedef_inherit \
|
||||||
typedef_mptr \
|
typedef_mptr \
|
||||||
|
|
@ -506,6 +513,7 @@ CPP_TEST_CASES += \
|
||||||
typemap_numinputs \
|
typemap_numinputs \
|
||||||
typemap_template \
|
typemap_template \
|
||||||
typemap_template_parm_typedef \
|
typemap_template_parm_typedef \
|
||||||
|
typemap_template_typedef \
|
||||||
typemap_out_optimal \
|
typemap_out_optimal \
|
||||||
typemap_qualifier_strip \
|
typemap_qualifier_strip \
|
||||||
typemap_variables \
|
typemap_variables \
|
||||||
|
|
@ -534,6 +542,7 @@ CPP_TEST_CASES += \
|
||||||
varargs_overload \
|
varargs_overload \
|
||||||
variable_replacement \
|
variable_replacement \
|
||||||
virtual_destructor \
|
virtual_destructor \
|
||||||
|
virtual_derivation \
|
||||||
virtual_poly \
|
virtual_poly \
|
||||||
virtual_vs_nonvirtual_base \
|
virtual_vs_nonvirtual_base \
|
||||||
voidtest \
|
voidtest \
|
||||||
|
|
@ -650,6 +659,7 @@ C_TEST_CASES += \
|
||||||
char_constant \
|
char_constant \
|
||||||
const_const \
|
const_const \
|
||||||
constant_expr \
|
constant_expr \
|
||||||
|
default_args_c \
|
||||||
empty_c \
|
empty_c \
|
||||||
enums \
|
enums \
|
||||||
enum_forward \
|
enum_forward \
|
||||||
|
|
@ -692,6 +702,7 @@ C_TEST_CASES += \
|
||||||
string_simple \
|
string_simple \
|
||||||
struct_rename \
|
struct_rename \
|
||||||
struct_initialization \
|
struct_initialization \
|
||||||
|
typedef_classforward_same_name \
|
||||||
typedef_struct \
|
typedef_struct \
|
||||||
typemap_subst \
|
typemap_subst \
|
||||||
union_parameter \
|
union_parameter \
|
||||||
|
|
|
||||||
|
|
@ -16,29 +16,51 @@
|
||||||
|
|
||||||
%inline
|
%inline
|
||||||
{
|
{
|
||||||
std::complex<double> Conj(const std::complex<double>& a)
|
std::complex<double> Conj(std::complex<double> a)
|
||||||
{
|
{
|
||||||
return std::conj(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);
|
return std::conj(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 1
|
std::vector<std::complex<double> > CopyHalf(std::vector<std::complex<double> > a)
|
||||||
std::vector<std::complex<double> > Copy_h(const std::vector<std::complex<double> >& a)
|
|
||||||
{
|
{
|
||||||
std::vector<std::complex<double> > b(a.size()/2);
|
std::vector<std::complex<double> > b(a.size()/2);
|
||||||
std::copy(a.begin(), a.begin()+a.size()/2, b.begin());
|
std::copy(a.begin(), a.begin()+a.size()/2, b.begin());
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
struct ComplexPair
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,16 @@
|
||||||
%module(directors="1") cpp11_directors
|
%module(directors="1") cpp11_directors
|
||||||
%feature("director");
|
%feature("director");
|
||||||
|
|
||||||
%{
|
%inline %{
|
||||||
|
|
||||||
class Foo {
|
class Foo {
|
||||||
public:
|
public:
|
||||||
virtual ~Foo() noexcept {}
|
virtual ~Foo() noexcept {}
|
||||||
virtual int ping() noexcept = 0;
|
virtual int ping() noexcept = 0;
|
||||||
virtual int pong() 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;
|
|
||||||
};
|
|
||||||
|
|
@ -6,6 +6,16 @@
|
||||||
%warnfilter(SWIGWARN_PARSE_KEYWORD) final; // 'final' is a java keyword, renaming to '_final'
|
%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'
|
%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 %{
|
%inline %{
|
||||||
|
|
||||||
struct Base {
|
struct Base {
|
||||||
|
|
@ -131,3 +141,12 @@ void DerivedNoVirtualStruct::cd() {}
|
||||||
void DerivedNoVirtualStruct::ef() {}
|
void DerivedNoVirtualStruct::ef() {}
|
||||||
DerivedNoVirtualStruct::~DerivedNoVirtualStruct() {}
|
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
|
||||||
|
%}
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,16 @@
|
||||||
%warnfilter(SWIGWARN_CPP11_LAMBDA) Space1::lambda19;
|
%warnfilter(SWIGWARN_CPP11_LAMBDA) Space1::lambda19;
|
||||||
%warnfilter(SWIGWARN_CPP11_LAMBDA) Space1::Space2::lambda20;
|
%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 %{
|
%inline %{
|
||||||
/* Defined lambda function with return value. */
|
/* Defined lambda function with return value. */
|
||||||
auto lambda1 = [](int x, int y) -> int { return x+y; };
|
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; })());
|
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
|
||||||
|
%}
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,10 @@
|
||||||
|
|
||||||
class Foo
|
class Foo
|
||||||
{
|
{
|
||||||
|
int m;
|
||||||
public:
|
public:
|
||||||
Foo(int i) : m(i) {}
|
Foo(int i) : m(i) {}
|
||||||
int get_m() { return m;}
|
int get_m() { return m;}
|
||||||
int m;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
std::shared_ptr<Foo> foo(Foo v) {
|
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
|
class Foo
|
||||||
{
|
{
|
||||||
|
int m;
|
||||||
public:
|
public:
|
||||||
Foo(int i);
|
Foo(int i);
|
||||||
int get_m();
|
int get_m();
|
||||||
int m;
|
|
||||||
};
|
};
|
||||||
std::shared_ptr<Foo> foo(Foo v);
|
std::shared_ptr<Foo> foo(Foo v);
|
||||||
std::shared_ptr<const Foo> const_foo(Foo v);
|
std::shared_ptr<const Foo> const_foo(Foo v);
|
||||||
|
|
|
||||||
|
|
@ -15,11 +15,11 @@ class C;
|
||||||
%inline %{
|
%inline %{
|
||||||
|
|
||||||
class C {
|
class C {
|
||||||
|
int m;
|
||||||
public:
|
public:
|
||||||
C() : m(-1) {}
|
C() : m(-1) {}
|
||||||
C(int i) : m(i) {}
|
C(int i) : m(i) {}
|
||||||
int get_m() { return m; }
|
int get_m() { return m; }
|
||||||
int m;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
|
||||||
89
Examples/test-suite/cpp11_shared_ptr_overload.i
Normal file
89
Examples/test-suite/cpp11_shared_ptr_overload.i
Normal 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 ""; }
|
||||||
|
%}
|
||||||
|
|
@ -16,19 +16,19 @@
|
||||||
%{
|
%{
|
||||||
|
|
||||||
class Base {
|
class Base {
|
||||||
|
int m;
|
||||||
public:
|
public:
|
||||||
Base() : m(-1) {}
|
Base() : m(-1) {}
|
||||||
Base(int i) : m(i) {}
|
Base(int i) : m(i) {}
|
||||||
int get_m() { return m; }
|
int get_m() { return m; }
|
||||||
int m;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Derived : public Base {
|
class Derived : public Base {
|
||||||
|
int n;
|
||||||
public:
|
public:
|
||||||
Derived() : n(-2) {}
|
Derived() : n(-2) {}
|
||||||
Derived(int i) : n(i) {}
|
Derived(int i) : n(i) {}
|
||||||
int get_n() { return n; }
|
int get_n() { return n; }
|
||||||
int n;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::shared_ptr<Base> BasePtr;
|
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> >;
|
%template(DerivedMap) std::map<int, std::shared_ptr<Derived> >;
|
||||||
|
|
||||||
class Base {
|
class Base {
|
||||||
|
int m;
|
||||||
public:
|
public:
|
||||||
Base();
|
Base();
|
||||||
int get_m();
|
int get_m();
|
||||||
int m;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Derived : public Base {
|
class Derived : public Base {
|
||||||
|
int n;
|
||||||
public:
|
public:
|
||||||
Derived();
|
Derived();
|
||||||
Derived(int i);
|
Derived(int i);
|
||||||
int get_n();
|
int get_n();
|
||||||
int n;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::shared_ptr<Base> BasePtr;
|
typedef std::shared_ptr<Base> BasePtr;
|
||||||
|
|
@ -135,20 +135,20 @@ int base_num(std::map<int, BasePtr > v);
|
||||||
|
|
||||||
%inline %{
|
%inline %{
|
||||||
class Base2 {
|
class Base2 {
|
||||||
|
int m;
|
||||||
public:
|
public:
|
||||||
Base2() : m(-1) {}
|
Base2() : m(-1) {}
|
||||||
Base2(int i) : m(i) {}
|
Base2(int i) : m(i) {}
|
||||||
int get_m() { return m; }
|
int get_m() { return m; }
|
||||||
int m;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class Derived2 : public Base2 {
|
class Derived2 : public Base2 {
|
||||||
|
int n;
|
||||||
public:
|
public:
|
||||||
Derived2() : n(0) {}
|
Derived2() : n(0) {}
|
||||||
Derived2(int i) : n(i) {}
|
Derived2(int i) : n(i) {}
|
||||||
int get_n_2() { return n; }
|
int get_n_2() { return n; }
|
||||||
int n;
|
|
||||||
};
|
};
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,10 @@ CPP_TEST_CASES = \
|
||||||
li_boost_intrusive_ptr
|
li_boost_intrusive_ptr
|
||||||
|
|
||||||
CPP11_TEST_CASES = \
|
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 \
|
cpp11_strongly_typed_enumerations_simple \
|
||||||
|
|
||||||
include $(srcdir)/../common.mk
|
include $(srcdir)/../common.mk
|
||||||
|
|
|
||||||
|
|
@ -16,14 +16,23 @@ public class complextest_runme {
|
||||||
if ( complextest.Conjf(a) != Complex.Conjugate(a) )
|
if ( complextest.Conjf(a) != Complex.Conjugate(a) )
|
||||||
throw new Exception("std::complex<float> test failed");
|
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();
|
var vec = new VectorStdCplx();
|
||||||
vec.Add(new Complex(1, 2));
|
vec.Add(new Complex(1, 2));
|
||||||
vec.Add(new Complex(2, 3));
|
vec.Add(new Complex(2, 3));
|
||||||
vec.Add(new Complex(4, 3));
|
vec.Add(new Complex(4, 3));
|
||||||
vec.Add(new Complex(1, 0));
|
vec.Add(new Complex(1, 0));
|
||||||
|
|
||||||
if ( complextest.Copy_h(vec).Count != 2 )
|
if ( complextest.CopyHalf(vec).Count != 2 )
|
||||||
throw new Exception("vector<complex> test failed");
|
throw new Exception("CopyHalf test failed");
|
||||||
|
|
||||||
|
if ( complextest.CopyHalfRef(vec).Count != 2 )
|
||||||
|
throw new Exception("CopyHalfRef test failed");
|
||||||
|
|
||||||
var p = new ComplexPair();
|
var p = new ComplexPair();
|
||||||
p.z1 = new Complex(0, 1);
|
p.z1 = new Complex(0, 1);
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ Expected output if PrintDebug enabled:
|
||||||
Base - Val(444.555)
|
Base - Val(444.555)
|
||||||
Base - Ref(444.555)
|
Base - Ref(444.555)
|
||||||
Base - Ptr(444.555)
|
Base - Ptr(444.555)
|
||||||
|
Base - ConstPtrRef(444.555)
|
||||||
Base - FullyOverloaded(int 10)
|
Base - FullyOverloaded(int 10)
|
||||||
Base - FullyOverloaded(bool 1)
|
Base - FullyOverloaded(bool 1)
|
||||||
Base - SemiOverloaded(int -678)
|
Base - SemiOverloaded(int -678)
|
||||||
|
|
@ -26,6 +27,7 @@ Base - DefaultParms(10, 1.1)
|
||||||
Derived - Val(444.555)
|
Derived - Val(444.555)
|
||||||
Derived - Ref(444.555)
|
Derived - Ref(444.555)
|
||||||
Derived - Ptr(444.555)
|
Derived - Ptr(444.555)
|
||||||
|
Derived - ConstPtrRef(444.555)
|
||||||
Derived - FullyOverloaded(int 10)
|
Derived - FullyOverloaded(int 10)
|
||||||
Derived - FullyOverloaded(bool 1)
|
Derived - FullyOverloaded(bool 1)
|
||||||
Derived - SemiOverloaded(int -678)
|
Derived - SemiOverloaded(int -678)
|
||||||
|
|
@ -36,6 +38,7 @@ Derived - DefaultParms(10, 1.1)
|
||||||
CSharpDerived - Val(444.555)
|
CSharpDerived - Val(444.555)
|
||||||
CSharpDerived - Ref(444.555)
|
CSharpDerived - Ref(444.555)
|
||||||
CSharpDerived - Ptr(444.555)
|
CSharpDerived - Ptr(444.555)
|
||||||
|
CSharpDerived - ConstPtrRef(444.555)
|
||||||
CSharpDerived - FullyOverloaded(int 10)
|
CSharpDerived - FullyOverloaded(int 10)
|
||||||
CSharpDerived - FullyOverloaded(bool True)
|
CSharpDerived - FullyOverloaded(bool True)
|
||||||
CSharpDerived - SemiOverloaded(-678)
|
CSharpDerived - SemiOverloaded(-678)
|
||||||
|
|
@ -99,6 +102,7 @@ public class runme
|
||||||
if (myCaller.ValCall(dh).val != dh.val) throw new Exception("failed");
|
if (myCaller.ValCall(dh).val != dh.val) throw new Exception("failed");
|
||||||
if (myCaller.RefCall(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.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)
|
// Fully overloaded method test (all methods in base class are overloaded)
|
||||||
if (NAMESPACE + myCaller.FullyOverloadedCall(10) != myBase.GetType() + "::FullyOverloaded(int)") throw new Exception("failed");
|
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);
|
if (director_classes.PrintDebug) Console.WriteLine("CSharpDerived - Ptr({0})", x.val);
|
||||||
return x;
|
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)
|
public override String FullyOverloaded(int x)
|
||||||
{
|
{
|
||||||
if (director_classes.PrintDebug) Console.WriteLine("CSharpDerived - FullyOverloaded(int {0})", x);
|
if (director_classes.PrintDebug) Console.WriteLine("CSharpDerived - FullyOverloaded(int {0})", x);
|
||||||
|
|
|
||||||
111
Examples/test-suite/csharp/li_boost_shared_ptr_director_runme.cs
Normal file
111
Examples/test-suite/csharp/li_boost_shared_ptr_director_runme.cs
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -177,6 +177,17 @@ public class li_std_vector_runme {
|
||||||
if (doubleArray[i] != dvCopy[i])
|
if (doubleArray[i] != dvCopy[i])
|
||||||
throw new Exception("Copy constructor failed, index:" + 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
|
// Repeat() test
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,12 @@ CPP_TEST_CASES = \
|
||||||
d_nativepointers \
|
d_nativepointers \
|
||||||
exception_partial_info
|
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
|
include $(srcdir)/../common.mk
|
||||||
|
|
||||||
# Overridden variables here
|
# Overridden variables here
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
* Base - Val(444.555)
|
* Base - Val(444.555)
|
||||||
* Base - Ref(444.555)
|
* Base - Ref(444.555)
|
||||||
* Base - Ptr(444.555)
|
* Base - Ptr(444.555)
|
||||||
|
* Base - ConstPtrRef(444.555)
|
||||||
* Base - FullyOverloaded(int 10)
|
* Base - FullyOverloaded(int 10)
|
||||||
* Base - FullyOverloaded(bool 1)
|
* Base - FullyOverloaded(bool 1)
|
||||||
* Base - SemiOverloaded(int -678)
|
* Base - SemiOverloaded(int -678)
|
||||||
|
|
@ -28,6 +29,7 @@
|
||||||
* Derived - Val(444.555)
|
* Derived - Val(444.555)
|
||||||
* Derived - Ref(444.555)
|
* Derived - Ref(444.555)
|
||||||
* Derived - Ptr(444.555)
|
* Derived - Ptr(444.555)
|
||||||
|
* Derived - ConstPtrRef(444.555)
|
||||||
* Derived - FullyOverloaded(int 10)
|
* Derived - FullyOverloaded(int 10)
|
||||||
* Derived - FullyOverloaded(bool 1)
|
* Derived - FullyOverloaded(bool 1)
|
||||||
* Derived - SemiOverloaded(int -678)
|
* Derived - SemiOverloaded(int -678)
|
||||||
|
|
@ -38,6 +40,7 @@
|
||||||
* DDerived - Val(444.555)
|
* DDerived - Val(444.555)
|
||||||
* DDerived - Ref(444.555)
|
* DDerived - Ref(444.555)
|
||||||
* DDerived - Ptr(444.555)
|
* DDerived - Ptr(444.555)
|
||||||
|
* DDerived - ConstPtrRef(444.555)
|
||||||
* DDerived - FullyOverloaded(int 10)
|
* DDerived - FullyOverloaded(int 10)
|
||||||
* DDerived - FullyOverloaded(bool True)
|
* DDerived - FullyOverloaded(bool True)
|
||||||
* DDerived - SemiOverloaded(-678)
|
* DDerived - SemiOverloaded(-678)
|
||||||
|
|
@ -96,6 +99,7 @@ void makeCalls(Caller myCaller, Base myBase) {
|
||||||
if (myCaller.ValCall(dh).val != dh.val) throw new Exception("[1] failed");
|
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.RefCall(dh).val != dh.val) throw new Exception("[2] failed");
|
||||||
if (myCaller.PtrCall(dh).val != dh.val) throw new Exception("[3] 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)
|
// Fully overloaded method test (all methods in base class are overloaded)
|
||||||
if (myCaller.FullyOverloadedCall(10) != myBaseType ~ "::FullyOverloaded(int)") throw new Exception("[4] failed");
|
if (myCaller.FullyOverloadedCall(10) != myBaseType ~ "::FullyOverloaded(int)") throw new Exception("[4] failed");
|
||||||
|
|
@ -136,6 +140,11 @@ public class DDerived : Base {
|
||||||
return x;
|
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) {
|
public override char[] FullyOverloaded(int x) {
|
||||||
if (PrintDebug) Stdout.formatln("DDerived - FullyOverloaded(int {0})", x);
|
if (PrintDebug) Stdout.formatln("DDerived - FullyOverloaded(int {0})", x);
|
||||||
return "DDerived::FullyOverloaded(int)";
|
return "DDerived::FullyOverloaded(int)";
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
* Base - Val(444.555)
|
* Base - Val(444.555)
|
||||||
* Base - Ref(444.555)
|
* Base - Ref(444.555)
|
||||||
* Base - Ptr(444.555)
|
* Base - Ptr(444.555)
|
||||||
|
* Base - ConstPtrRef(444.555)
|
||||||
* Base - FullyOverloaded(int 10)
|
* Base - FullyOverloaded(int 10)
|
||||||
* Base - FullyOverloaded(bool 1)
|
* Base - FullyOverloaded(bool 1)
|
||||||
* Base - SemiOverloaded(int -678)
|
* Base - SemiOverloaded(int -678)
|
||||||
|
|
@ -28,6 +29,7 @@
|
||||||
* Derived - Val(444.555)
|
* Derived - Val(444.555)
|
||||||
* Derived - Ref(444.555)
|
* Derived - Ref(444.555)
|
||||||
* Derived - Ptr(444.555)
|
* Derived - Ptr(444.555)
|
||||||
|
* Derived - ConstPtrRef(444.555)
|
||||||
* Derived - FullyOverloaded(int 10)
|
* Derived - FullyOverloaded(int 10)
|
||||||
* Derived - FullyOverloaded(bool 1)
|
* Derived - FullyOverloaded(bool 1)
|
||||||
* Derived - SemiOverloaded(int -678)
|
* Derived - SemiOverloaded(int -678)
|
||||||
|
|
@ -38,6 +40,7 @@
|
||||||
* DDerived - Val(444.555)
|
* DDerived - Val(444.555)
|
||||||
* DDerived - Ref(444.555)
|
* DDerived - Ref(444.555)
|
||||||
* DDerived - Ptr(444.555)
|
* DDerived - Ptr(444.555)
|
||||||
|
* DDerived - ConstPtrRef(444.555)
|
||||||
* DDerived - FullyOverloaded(int 10)
|
* DDerived - FullyOverloaded(int 10)
|
||||||
* DDerived - FullyOverloaded(bool true)
|
* DDerived - FullyOverloaded(bool true)
|
||||||
* DDerived - SemiOverloaded(-678)
|
* DDerived - SemiOverloaded(-678)
|
||||||
|
|
@ -97,6 +100,7 @@ void makeCalls(Caller myCaller, Base myBase) {
|
||||||
enforce(myCaller.ValCall(dh).val == dh.val, "[1] failed");
|
enforce(myCaller.ValCall(dh).val == dh.val, "[1] failed");
|
||||||
enforce(myCaller.RefCall(dh).val == dh.val, "[2] failed");
|
enforce(myCaller.RefCall(dh).val == dh.val, "[2] failed");
|
||||||
enforce(myCaller.PtrCall(dh).val == dh.val, "[3] 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)
|
// Fully overloaded method test (all methods in base class are overloaded)
|
||||||
enforce(myCaller.FullyOverloadedCall(10) == myBaseType ~ "::FullyOverloaded(int)", "[4] failed");
|
enforce(myCaller.FullyOverloadedCall(10) == myBaseType ~ "::FullyOverloaded(int)", "[4] failed");
|
||||||
|
|
@ -137,6 +141,11 @@ public class DDerived : Base {
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override DoubleHolder ConstPtrRef(DoubleHolder x) {
|
||||||
|
if (PrintDebug) writefln("DDerived - ConstPtrRef(%s)", x.val);
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
public override string FullyOverloaded(int x) {
|
public override string FullyOverloaded(int x) {
|
||||||
if (PrintDebug) writefln("DDerived - FullyOverloaded(int %s)", x);
|
if (PrintDebug) writefln("DDerived - FullyOverloaded(int %s)", x);
|
||||||
return "DDerived::FullyOverloaded(int)";
|
return "DDerived::FullyOverloaded(int)";
|
||||||
|
|
|
||||||
114
Examples/test-suite/d/li_boost_shared_ptr_director_runme.2.d
Normal file
114
Examples/test-suite/d/li_boost_shared_ptr_director_runme.2.d
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
30
Examples/test-suite/default_arg_expressions.i
Normal file
30
Examples/test-suite/default_arg_expressions.i
Normal 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) {}
|
||||||
|
%}
|
||||||
|
|
@ -28,6 +28,13 @@
|
||||||
int value_perm(int first, int mode = 0640 | 0004) { return mode; }
|
int value_perm(int first, int mode = 0640 | 0004) { return mode; }
|
||||||
int value_m01(int first, int val = -01) { return val; }
|
int value_m01(int first, int val = -01) { return val; }
|
||||||
bool booltest2(bool x = 0 | 1) { return x; }
|
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) {}
|
void doublevalue1(int first, double num = 0.0e-1) {}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,13 @@
|
||||||
%module default_args_c
|
%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 */
|
/* Default arguments for C code */
|
||||||
int foo1(int x = 42 || 3);
|
int foo1(int x = 42 || 3);
|
||||||
int foo43(int x = 42 | 3);
|
int foo43(int x = 42 | 3);
|
||||||
|
|
|
||||||
|
|
@ -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::Ref;
|
||||||
%warnfilter(SWIGWARN_TYPEMAP_THREAD_UNSAFE,SWIGWARN_TYPEMAP_DIRECTOROUT_PTR) Base::Ptr;
|
%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
|
%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 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& 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* 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(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)"; }
|
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 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& 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* 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(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)"; }
|
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 ValCall(DoubleHolder x) { return m_base->Val(x); }
|
||||||
DoubleHolder& RefCall(DoubleHolder& x) { return m_base->Ref(x); }
|
DoubleHolder& RefCall(DoubleHolder& x) { return m_base->Ref(x); }
|
||||||
DoubleHolder* PtrCall(DoubleHolder* x) { return m_base->Ptr(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(int x) { return m_base->FullyOverloaded(x); }
|
||||||
std::string FullyOverloadedCall(bool 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); }
|
std::string SemiOverloadedCall(int x) { return m_base->SemiOverloaded(x); }
|
||||||
|
|
|
||||||
|
|
@ -23,11 +23,7 @@ namespace Swig {
|
||||||
class DirectorException {};
|
class DirectorException {};
|
||||||
class DirectorMethodException: public Swig::DirectorException {};
|
class DirectorMethodException: public Swig::DirectorException {};
|
||||||
}
|
}
|
||||||
#ifndef SWIG_fail
|
|
||||||
#define SWIG_fail
|
|
||||||
#endif
|
|
||||||
#endif /* !SWIG_DIRECTORS */
|
#endif /* !SWIG_DIRECTORS */
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%include "std_string.i"
|
%include "std_string.i"
|
||||||
|
|
|
||||||
25
Examples/test-suite/director_exception_catches.i
Normal file
25
Examples/test-suite/director_exception_catches.i
Normal 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() {}
|
||||||
|
};
|
||||||
|
%}
|
||||||
72
Examples/test-suite/director_ownership.i
Normal file
72
Examples/test-suite/director_ownership.i
Normal 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
|
||||||
|
%}
|
||||||
4
Examples/test-suite/errors/cpp_invalid_exponents1.i
Normal file
4
Examples/test-suite/errors/cpp_invalid_exponents1.i
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
%module xxx
|
||||||
|
|
||||||
|
void bad(double nn = 5e);
|
||||||
|
|
||||||
2
Examples/test-suite/errors/cpp_invalid_exponents1.stderr
Normal file
2
Examples/test-suite/errors/cpp_invalid_exponents1.stderr
Normal 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).
|
||||||
4
Examples/test-suite/errors/cpp_invalid_exponents2.i
Normal file
4
Examples/test-suite/errors/cpp_invalid_exponents2.i
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
%module xxx
|
||||||
|
|
||||||
|
void bad(double nn = 6.6e);
|
||||||
|
|
||||||
2
Examples/test-suite/errors/cpp_invalid_exponents2.stderr
Normal file
2
Examples/test-suite/errors/cpp_invalid_exponents2.stderr
Normal 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).
|
||||||
51
Examples/test-suite/errors/cpp_template_duplicate_names.i
Normal file
51
Examples/test-suite/errors/cpp_template_duplicate_names.i
Normal 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>;
|
||||||
|
|
||||||
|
|
@ -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'.
|
||||||
43
Examples/test-suite/errors/pp_expressions_bad.i
Normal file
43
Examples/test-suite/errors/pp_expressions_bad.i
Normal 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
|
||||||
19
Examples/test-suite/errors/pp_expressions_bad.stderr
Normal file
19
Examples/test-suite/errors/pp_expressions_bad.stderr
Normal 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)".
|
||||||
7
Examples/test-suite/errors/pp_invalid_exponents.i
Normal file
7
Examples/test-suite/errors/pp_invalid_exponents.i
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
%module xxx
|
||||||
|
|
||||||
|
#if 123e
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 456.e
|
||||||
|
#endif
|
||||||
6
Examples/test-suite/errors/pp_invalid_exponents.stderr
Normal file
6
Examples/test-suite/errors/pp_invalid_exponents.stderr
Normal 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'
|
||||||
|
|
@ -6,6 +6,10 @@
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
|
#pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
|
||||||
#endif
|
#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"
|
#warning "UTL needs fixing for partial exception information"
|
||||||
#endif
|
#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
|
||||||
|
%}
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,8 @@
|
||||||
(check (=~ (foo 1 2 "bar" 4) 15))
|
(check (=~ (foo 1 2 "bar" 4) 15))
|
||||||
|
|
||||||
;; Check second method
|
;; Check second method
|
||||||
(check (=~ (foo 1 2) 4811.4))
|
(check (=~ (foo 1 2) 118))
|
||||||
(check (=~ (foo 1 2 3.2) 4797.2))
|
(check (=~ (foo 1 2 3.2) 104))
|
||||||
(check (=~ (foo 1 2 3.2 #\Q) 4798.2))
|
(check (=~ (foo 1 2 3.2 #\Q) 4798))
|
||||||
|
|
||||||
(exit 0)
|
(exit 0)
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,10 @@ template<class T> class vector {
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
|
#pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
|
||||||
#endif
|
#endif
|
||||||
|
#if __GNUC__ >= 7
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wdeprecated" // dynamic exception specifications are deprecated in C++11
|
||||||
|
#endif
|
||||||
|
|
||||||
class Base {
|
class Base {
|
||||||
public:
|
public:
|
||||||
|
|
@ -70,6 +74,9 @@ public:
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
|
#pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
|
||||||
#endif
|
#endif
|
||||||
|
#if __GNUC__ >= 7
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%template(maxint) maximum<int>;
|
%template(maxint) maximum<int>;
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,10 @@ CPP_TEST_CASES = \
|
||||||
# li_boost_intrusive_ptr
|
# li_boost_intrusive_ptr
|
||||||
|
|
||||||
CPP11_TEST_CASES = \
|
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 \
|
cpp11_strongly_typed_enumerations_simple \
|
||||||
|
|
||||||
DOXYGEN_TEST_CASES := \
|
DOXYGEN_TEST_CASES := \
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ public class class_scope_namespace_runme {
|
||||||
F f = new F();
|
F f = new F();
|
||||||
G g = new G();
|
G g = new G();
|
||||||
H.HH h = new H.HH();
|
H.HH h = new H.HH();
|
||||||
I.II i = new I.II();
|
I_.II i = new I_.II();
|
||||||
J j = new J();
|
J j = new J();
|
||||||
K k = new K();
|
K k = new K();
|
||||||
L l = new L();
|
L l = new L();
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -16,6 +16,7 @@ Expected output if PrintDebug enabled:
|
||||||
Base - Val(444.555)
|
Base - Val(444.555)
|
||||||
Base - Ref(444.555)
|
Base - Ref(444.555)
|
||||||
Base - Ptr(444.555)
|
Base - Ptr(444.555)
|
||||||
|
Base - ConstPtrRef(444.555)
|
||||||
Base - FullyOverloaded(int 10)
|
Base - FullyOverloaded(int 10)
|
||||||
Base - FullyOverloaded(bool 1)
|
Base - FullyOverloaded(bool 1)
|
||||||
Base - SemiOverloaded(int -678)
|
Base - SemiOverloaded(int -678)
|
||||||
|
|
@ -26,6 +27,7 @@ Base - DefaultParms(10, 1.1)
|
||||||
Derived - Val(444.555)
|
Derived - Val(444.555)
|
||||||
Derived - Ref(444.555)
|
Derived - Ref(444.555)
|
||||||
Derived - Ptr(444.555)
|
Derived - Ptr(444.555)
|
||||||
|
Derived - ConstPtrRef(444.555)
|
||||||
Derived - FullyOverloaded(int 10)
|
Derived - FullyOverloaded(int 10)
|
||||||
Derived - FullyOverloaded(bool 1)
|
Derived - FullyOverloaded(bool 1)
|
||||||
Derived - SemiOverloaded(int -678)
|
Derived - SemiOverloaded(int -678)
|
||||||
|
|
@ -36,6 +38,7 @@ Derived - DefaultParms(10, 1.1)
|
||||||
JavaDerived - Val(444.555)
|
JavaDerived - Val(444.555)
|
||||||
JavaDerived - Ref(444.555)
|
JavaDerived - Ref(444.555)
|
||||||
JavaDerived - Ptr(444.555)
|
JavaDerived - Ptr(444.555)
|
||||||
|
JavaDerived - ConstPtrRef(444.555)
|
||||||
JavaDerived - FullyOverloaded(int 10)
|
JavaDerived - FullyOverloaded(int 10)
|
||||||
JavaDerived - FullyOverloaded(bool True)
|
JavaDerived - FullyOverloaded(bool True)
|
||||||
JavaDerived - SemiOverloaded(-678)
|
JavaDerived - SemiOverloaded(-678)
|
||||||
|
|
@ -111,6 +114,7 @@ public class director_classes_runme {
|
||||||
if (myCaller.ValCall(dh).getVal() != dh.getVal()) throw new RuntimeException("failed");
|
if (myCaller.ValCall(dh).getVal() != dh.getVal()) throw new RuntimeException("failed");
|
||||||
if (myCaller.RefCall(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.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)
|
// Fully overloaded method test (all methods in base class are overloaded)
|
||||||
if (!myCaller.FullyOverloadedCall(10).equals(baseSimpleName + "::FullyOverloaded(int)")) {
|
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() + ")");
|
if (director_classes.getPrintDebug()) System.out.println("JavaDerived - Ptr(" + x.getVal() + ")");
|
||||||
return x;
|
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)
|
public String FullyOverloaded(int x)
|
||||||
{
|
{
|
||||||
if (director_classes.getPrintDebug()) System.out.println("JavaDerived - FullyOverloaded(int " + x + ")");
|
if (director_classes.getPrintDebug()) System.out.println("JavaDerived - FullyOverloaded(int " + x + ")");
|
||||||
|
|
|
||||||
|
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
42
Examples/test-suite/java/director_ownership_runme.java
Normal file
42
Examples/test-suite/java/director_ownership_runme.java
Normal 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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -126,19 +126,28 @@ public class java_director_exception_feature_nspace_runme {
|
||||||
try { b.genericpong(1); fail("No exception thrown in genericpong(1)"); }
|
try { b.genericpong(1); fail("No exception thrown in genericpong(1)"); }
|
||||||
catch (MyJavaException1 e) {
|
catch (MyJavaException1 e) {
|
||||||
failif( ! java_director_exception_feature_nspace_Consts.GENERICPONGEXCP1.equals(e.getMessage()), "Expected exception has unexpected message: '" + e.getMessage() + "'");
|
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)");}
|
try { b.genericpong(2); fail("No exception thrown in genericpong(2)");}
|
||||||
catch (java_director_exception_feature_nspace_NewCheckedException e) {
|
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() + "'");
|
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)");}
|
try { b.genericpong(3); fail("No exception thrown in genericpong(3)");}
|
||||||
catch (java_director_exception_feature_nspace_NewUncheckedException e) {
|
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() + "'");
|
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)");}
|
try { b.genericpong(4); fail("No exception thrown in genericpong(4)");}
|
||||||
catch (RuntimeException e) {
|
catch (RuntimeException e) {
|
||||||
failif ( e.getClass() != RuntimeException.class, "Exception " + e + " is not exactly RumtimeException");
|
failif ( e.getClass() != RuntimeException.class, "Exception " + e + " is not exactly RuntimeException");
|
||||||
failif( ! java_director_exception_feature_nspace_Consts.GENERICPONGEXCP4.equals(e.getMessage()), "Expected exception has unexpected message: '" + e.getMessage() + "'");
|
failif( ! "Unspecified DirectorException message".equals(e.getMessage()), "Expected exception has unexpected message: '" + e.getMessage() + "'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
|
|
|
||||||
|
|
@ -127,19 +127,28 @@ public class java_director_exception_feature_runme {
|
||||||
try { b.genericpong(1); fail("No exception thrown in genericpong(1)"); }
|
try { b.genericpong(1); fail("No exception thrown in genericpong(1)"); }
|
||||||
catch (MyJavaException1 e) {
|
catch (MyJavaException1 e) {
|
||||||
failif( ! java_director_exception_feature_Consts.GENERICPONGEXCP1.equals(e.getMessage()), "Expected exception has unexpected message: '" + e.getMessage() + "'");
|
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)");}
|
try { b.genericpong(2); fail("No exception thrown in genericpong(2)");}
|
||||||
catch (NewCheckedException e) {
|
catch (NewCheckedException e) {
|
||||||
failif( ! java_director_exception_feature_Consts.GENERICPONGEXCP2.equals(e.getMessage()), "Expected exception has unexpected message: '" + e.getMessage() + "'");
|
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)");}
|
try { b.genericpong(3); fail("No exception thrown in genericpong(3)");}
|
||||||
catch (NewUncheckedException e) {
|
catch (NewUncheckedException e) {
|
||||||
failif( ! java_director_exception_feature_Consts.GENERICPONGEXCP3.equals(e.getMessage()), "Expected exception has unexpected message: '" + e.getMessage() + "'");
|
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)");}
|
try { b.genericpong(4); fail("No exception thrown in genericpong(4)");}
|
||||||
catch (RuntimeException e) {
|
catch (RuntimeException e) {
|
||||||
failif ( e.getClass() != RuntimeException.class, "Exception " + e + " is not exactly RumtimeException");
|
failif ( e.getClass() != RuntimeException.class, "Exception " + e + " is not exactly RuntimeException");
|
||||||
failif( ! java_director_exception_feature_Consts.GENERICPONGEXCP4.equals(e.getMessage()), "Expected exception has unexpected message: '" + e.getMessage() + "'");
|
failif( ! "Unspecified DirectorException message".equals(e.getMessage()), "Expected exception has unexpected message: '" + e.getMessage() + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -93,6 +93,28 @@ public class java_throws_runme {
|
||||||
if (!pass)
|
if (!pass)
|
||||||
throw new RuntimeException("Test 6 failed");
|
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
|
// Global function
|
||||||
pass = false;
|
pass = false;
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
static {
|
||||||
try {
|
try {
|
||||||
System.loadLibrary("li_boost_shared_ptr");
|
System.loadLibrary("li_boost_shared_ptr_director");
|
||||||
} catch (UnsatisfiedLinkError e) {
|
} 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.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);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void check(String got, String expected) {
|
private static void check(int got, int expected) {
|
||||||
if (!got.equals(expected))
|
if (got != expected)
|
||||||
throw new RuntimeException("Failed, got: " + got + " expected: " + expected);
|
throw new RuntimeException("Failed, got: " + got + " expected: " + expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String argv[]) {
|
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 a = new li_boost_shared_ptr_director_Derived(false);
|
||||||
li_boost_shared_ptr_director_Derived b = li_boost_shared_ptr_director_Derived.new(true);
|
li_boost_shared_ptr_director_Derived b = new li_boost_shared_ptr_director_Derived(true);
|
||||||
|
|
||||||
check(call_ret_c_shared_ptr(a) == 1);
|
check(li_boost_shared_ptr_director.call_ret_c_shared_ptr(a), 1);
|
||||||
check(call_ret_c_shared_ptr(b) == -1);
|
check(li_boost_shared_ptr_director.call_ret_c_shared_ptr(b), -1);
|
||||||
check(call_ret_c_by_value(a) == 1);
|
check(li_boost_shared_ptr_director.call_ret_c_by_value(a), 1);
|
||||||
|
|
||||||
check(call_take_c_by_value(a) == 5);
|
check(li_boost_shared_ptr_director.call_ret_c_shared_ptr(a), 1);
|
||||||
check(call_take_c_shared_ptr_by_value(a) == 6);
|
check(li_boost_shared_ptr_director.call_ret_c_shared_ptr(b), -1);
|
||||||
check(call_take_c_shared_ptr_by_ref(a) == 7);
|
check(li_boost_shared_ptr_director.call_ret_c_by_value(a), 1);
|
||||||
check(call_take_c_shared_ptr_by_pointer(a) == 8);
|
|
||||||
check(call_take_c_shared_ptr_by_pointer_ref(a) == 9);
|
|
||||||
|
|
||||||
check(call_take_c_shared_ptr_by_value_with_null(a) == -2);
|
check(li_boost_shared_ptr_director.call_take_c_by_value(a), 5);
|
||||||
check(call_take_c_shared_ptr_by_ref_with_null(a) == -3);
|
check(li_boost_shared_ptr_director.call_take_c_by_ref(a), 6);
|
||||||
check(call_take_c_shared_ptr_by_pointer_with_null(a) == -4);
|
check(li_boost_shared_ptr_director.call_take_c_by_pointer(a), 7);
|
||||||
check(call_take_c_shared_ptr_by_pointer_ref_with_null(a) == -5);
|
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
|
private boolean return_none;
|
||||||
public String ping() {
|
|
||||||
return "li_boost_shared_ptr_director_MyBarFoo.ping()";
|
li_boost_shared_ptr_director_Derived(boolean flag) {
|
||||||
|
super();
|
||||||
|
this.return_none = flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String pong() {
|
public C ret_c_shared_ptr() {
|
||||||
return "li_boost_shared_ptr_director_MyBarFoo.pong();" + ping();
|
if (this.return_none)
|
||||||
|
return null;
|
||||||
|
else
|
||||||
|
return new C();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String upcall(li_boost_shared_ptr_director.FooBar fooBarPtr) {
|
public C ret_c_by_value() {
|
||||||
return "override;" + fooBarPtr.FooBarDo();
|
return new C();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public li_boost_shared_ptr_director.Foo makeFoo() {
|
public int take_c_by_value(C c) {
|
||||||
return new li_boost_shared_ptr_director.Foo();
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -23,10 +23,10 @@ public class template_partial_specialization_runme {
|
||||||
new G().g();
|
new G().g();
|
||||||
new H().h();
|
new H().h();
|
||||||
|
|
||||||
new I().i();
|
|
||||||
new J().j();
|
new J().j();
|
||||||
new K().k();
|
new K().k();
|
||||||
new L().l();
|
new M().m();
|
||||||
|
new N().n();
|
||||||
|
|
||||||
new BB().b();
|
new BB().b();
|
||||||
new BBB().b();
|
new BBB().b();
|
||||||
|
|
|
||||||
|
|
@ -23,10 +23,10 @@ public class template_partial_specialization_typedef_runme {
|
||||||
new G().g();
|
new G().g();
|
||||||
new H().h();
|
new H().h();
|
||||||
|
|
||||||
new I().i();
|
|
||||||
new J().j();
|
new J().j();
|
||||||
new K().k();
|
new K().k();
|
||||||
new L().l();
|
new M().m();
|
||||||
|
new N().n();
|
||||||
|
|
||||||
new BB().b();
|
new BB().b();
|
||||||
new BBB().b();
|
new BBB().b();
|
||||||
|
|
|
||||||
|
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -42,7 +42,6 @@
|
||||||
%feature("director:except") MyNS::Foo::ping {
|
%feature("director:except") MyNS::Foo::ping {
|
||||||
jthrowable $error = jenv->ExceptionOccurred();
|
jthrowable $error = jenv->ExceptionOccurred();
|
||||||
if ($error) {
|
if ($error) {
|
||||||
jenv->ExceptionClear(); // clear java exception since mapping to c++ exception
|
|
||||||
if (Swig::ExceptionMatches(jenv,$error,"$packagepath/MyJavaException1")) {
|
if (Swig::ExceptionMatches(jenv,$error,"$packagepath/MyJavaException1")) {
|
||||||
throw 1;
|
throw 1;
|
||||||
} else if (Swig::ExceptionMatches(jenv,$error,"$packagepath/MyJavaException2")) {
|
} else if (Swig::ExceptionMatches(jenv,$error,"$packagepath/MyJavaException2")) {
|
||||||
|
|
@ -71,7 +70,6 @@
|
||||||
%feature("director:except") MyNS::Foo::pong %{
|
%feature("director:except") MyNS::Foo::pong %{
|
||||||
jthrowable $error = jenv->ExceptionOccurred();
|
jthrowable $error = jenv->ExceptionOccurred();
|
||||||
if ($error) {
|
if ($error) {
|
||||||
jenv->ExceptionClear();
|
|
||||||
$directorthrowshandlers
|
$directorthrowshandlers
|
||||||
throw ::MyNS::Unexpected(Swig::JavaExceptionMessage(jenv,$error).message());
|
throw ::MyNS::Unexpected(Swig::JavaExceptionMessage(jenv,$error).message());
|
||||||
}
|
}
|
||||||
|
|
@ -121,7 +119,10 @@
|
||||||
%feature("director:except") MyNS::Foo::genericpong {
|
%feature("director:except") MyNS::Foo::genericpong {
|
||||||
jthrowable $error = jenv->ExceptionOccurred();
|
jthrowable $error = jenv->ExceptionOccurred();
|
||||||
if ($error) {
|
if ($error) {
|
||||||
jenv->ExceptionClear();
|
if (Swig::ExceptionMatches(jenv,$error,"UnconstructableException")) {
|
||||||
|
// Purposefully test NULL
|
||||||
|
throw Swig::DirectorException(jenv, NULL);
|
||||||
|
}
|
||||||
throw Swig::DirectorException(jenv,$error);
|
throw Swig::DirectorException(jenv,$error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -131,9 +132,10 @@
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%feature ("except",throws="Exception") MyNS::Bar::genericpong %{
|
%feature ("except",throws="Exception") MyNS::Bar::genericpong %{
|
||||||
try { $action }
|
try {
|
||||||
catch (Swig::DirectorException & direxcp) {
|
$action
|
||||||
direxcp.raiseJavaException(jenv); // jenv always available in JNI code
|
} catch (Swig::DirectorException & direxcp) {
|
||||||
|
direxcp.throwException(jenv); // jenv always available in JNI code
|
||||||
return $null;
|
return $null;
|
||||||
}
|
}
|
||||||
%}
|
%}
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue