Merge branch 'master' into js-v8-52-tests
This commit is contained in:
commit
6c78195d75
459 changed files with 13117 additions and 4710 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -66,6 +66,7 @@ CCache/ccache_swig_config.h
|
|||
CCache/config.h
|
||||
CCache/config.log
|
||||
CCache/config.status
|
||||
CCache/config_win32.h
|
||||
Examples/Makefile
|
||||
Examples/d/example.mk
|
||||
Examples/guile/Makefile
|
||||
|
|
@ -85,6 +86,8 @@ swig.spec
|
|||
# Build Artifacts
|
||||
.dirstamp
|
||||
CCache/ccache-swig
|
||||
CCache/ccache-swig.1
|
||||
CCache/web/ccache-swig-man.html
|
||||
Lib/swigwarn.swg
|
||||
Source/CParse/parser.c
|
||||
Source/CParse/parser.h
|
||||
|
|
|
|||
64
.travis.yml
64
.travis.yml
|
|
@ -6,9 +6,6 @@ matrix:
|
|||
env: SWIGLANG=
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=
|
||||
|
|
@ -55,15 +52,23 @@ matrix:
|
|||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=javascript ENGINE=node VER=4
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=javascript ENGINE=node VER=6
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=javascript ENGINE=node VER=8
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=javascript ENGINE=node VER=10
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=javascript ENGINE=jsc
|
||||
|
|
@ -164,6 +169,11 @@ matrix:
|
|||
env: SWIGLANG=python PY3=3 VER=3.5
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=python PY3=3 VER=3.6
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=python SWIG_FEATURES=-builtin VER=2.6
|
||||
|
|
@ -174,6 +184,14 @@ matrix:
|
|||
env: SWIGLANG=python SWIG_FEATURES=-builtin
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- os: linux
|
||||
env: SWIGLANG=python SWIG_FEATURES=-builtin SWIG_CC=gcc-6 SWIG_CXX=g++-6 CPP11=1
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- os: linux
|
||||
env: SWIGLANG=python SWIG_FEATURES=-builtin SWIG_CC=gcc-6 SWIG_CXX=g++-6 CPP11=1 PY3=3 VER=3.6
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=python SWIG_FEATURES=-builtin PY3=3 VER=3.4
|
||||
|
|
@ -186,7 +204,12 @@ matrix:
|
|||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=python SWIG_FEATURES=-builtin PY3=3 VER=3.5 SWIGOPTPY3=
|
||||
env: SWIGLANG=python SWIG_FEATURES=-builtin PY3=3 VER=3.6
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=python SWIG_FEATURES=-builtin PY3=3 VER=3.6 SWIGOPTPY3=
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
|
|
@ -233,6 +256,10 @@ matrix:
|
|||
env: SWIGLANG=csharp SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP11=1
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- os: linux
|
||||
env: SWIGLANG=go SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP11=1
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- os: linux
|
||||
env: SWIGLANG=java SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP11=1
|
||||
sudo: required
|
||||
|
|
@ -241,14 +268,26 @@ matrix:
|
|||
env: SWIGLANG=python SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP11=1
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- os: linux
|
||||
env: SWIGLANG=r CPP11=1 # Note: making 'R CMD SHLIB' use a different compiler is non-trivial
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- os: linux
|
||||
env: SWIGLANG=ruby SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP11=1
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- os: linux
|
||||
env: SWIGLANG=tcl SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP11=1
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- os: linux
|
||||
env: SWIGLANG=csharp SWIG_CC=gcc-6 SWIG_CXX=g++-6 CPP14=1
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- os: linux
|
||||
env: SWIGLANG=go SWIG_CC=gcc-6 SWIG_CXX=g++-6 CPP14=1
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- os: linux
|
||||
env: SWIGLANG=java SWIG_CC=gcc-6 SWIG_CXX=g++-6 CPP14=1
|
||||
sudo: required
|
||||
|
|
@ -261,6 +300,18 @@ matrix:
|
|||
env: SWIGLANG=ruby SWIG_CC=gcc-6 SWIG_CXX=g++-6 CPP14=1
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- os: linux
|
||||
env: SWIGLANG=tcl SWIG_CC=gcc-6 SWIG_CXX=g++-6 CPP14=1
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- os: linux
|
||||
env: SWIGLANG=java SWIG_CC=gcc-7 SWIG_CXX=g++-7 CPP14=1
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- os: linux
|
||||
env: SWIGLANG=python SWIG_CC=gcc-7 SWIG_CXX=g++-7 CPP14=1
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: osx
|
||||
env: SWIGLANG=
|
||||
|
|
@ -302,10 +353,6 @@ matrix:
|
|||
env: SWIGLANG=tcl
|
||||
|
||||
allow_failures:
|
||||
# Started failing after upgrade from Guile 2.0.14 to Guile 2.2.0
|
||||
- compiler: clang
|
||||
os: osx
|
||||
env: SWIGLANG=guile
|
||||
# Lots of failing tests currently
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
|
|
@ -331,6 +378,7 @@ install:
|
|||
- if test "$TRAVIS_OS_NAME" = "osx"; then source Tools/travis-osx-install.sh; fi
|
||||
- if test -n "$CPP11"; then CONFIGOPTS+=(--enable-cpp11-testing --without-maximum-compile-warnings "CXXFLAGS=-std=c++11 -Wall -Wextra" "CFLAGS=-std=c11 -Wall -Wextra") && export CSTD=c11 && export CPPSTD=c++11; fi
|
||||
- if test -n "$CPP14"; then CONFIGOPTS+=(--enable-cpp11-testing --without-maximum-compile-warnings "CXXFLAGS=-std=c++14 -Wall -Wextra" "CFLAGS=-std=c11 -Wall -Wextra") && export CSTD=c11 && export CPPSTD=c++14; fi
|
||||
- if test -n "$CPP17"; then CONFIGOPTS+=(--enable-cpp11-testing --without-maximum-compile-warnings "CXXFLAGS=-std=c++17 -Wall -Wextra" "CFLAGS=-std=c11 -Wall -Wextra") && export CSTD=c11 && export CPPSTD=c++17; fi
|
||||
- ls -la $(which $CC)
|
||||
- ls -la $(which $CXX)
|
||||
- $CC --version
|
||||
|
|
|
|||
8
ANNOUNCE
8
ANNOUNCE
|
|
@ -1,8 +1,8 @@
|
|||
*** ANNOUNCE: SWIG 3.0.13 (in progress) ***
|
||||
*** ANNOUNCE: SWIG 4.0.0 (in progress) ***
|
||||
|
||||
http://www.swig.org
|
||||
|
||||
We're pleased to announce SWIG-3.0.13, the latest SWIG release.
|
||||
We're pleased to announce SWIG-4.0.0, the latest SWIG release.
|
||||
|
||||
What is SWIG?
|
||||
=============
|
||||
|
|
@ -27,11 +27,11 @@ Availability
|
|||
============
|
||||
The release is available for download on Sourceforge at
|
||||
|
||||
http://prdownloads.sourceforge.net/swig/swig-3.0.13.tar.gz
|
||||
http://prdownloads.sourceforge.net/swig/swig-4.0.0.tar.gz
|
||||
|
||||
A Windows version is also available at
|
||||
|
||||
http://prdownloads.sourceforge.net/swig/swigwin-3.0.13.zip
|
||||
http://prdownloads.sourceforge.net/swig/swigwin-4.0.0.zip
|
||||
|
||||
Please report problems with this release to the swig-devel mailing list,
|
||||
details at http://www.swig.org/mail.html.
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ bindir=@bindir@
|
|||
mandir=@mandir@
|
||||
INSTALLCMD=@INSTALL@
|
||||
PACKAGE_NAME=@PACKAGE_NAME@
|
||||
PROGRAM_NAME=@PROGRAM_NAME@
|
||||
# Soft link test can be skipped on systems that don't support soft linking
|
||||
NOSOFTLINKSTEST=
|
||||
|
||||
|
|
@ -17,13 +18,10 @@ SWIG=swig
|
|||
SWIG_LIB=../$(srcdir)/../Lib
|
||||
EXEEXT=@EXEEXT@
|
||||
|
||||
# Use standard autoconf approach to transform executable name using --program-prefix and --program-suffix
|
||||
transform = @program_transform_name@
|
||||
|
||||
LIBS= @LIBS@
|
||||
OBJS= ccache.o mdfour.o hash.o execute.o util.o args.o stats.o \
|
||||
cleanup.o snprintf.o unify.o
|
||||
HEADERS = ccache.h mdfour.h
|
||||
HEADERS = ccache.h mdfour.h config.h config_win32.h
|
||||
|
||||
all: $(PACKAGE_NAME)$(EXEEXT)
|
||||
|
||||
|
|
@ -32,7 +30,7 @@ Makefile: $(srcdir)/Makefile.in ./config.status
|
|||
$(SHELL) ./config.status
|
||||
|
||||
# Note that HTML documentation is actually generated and used from the main SWIG documentation Makefile
|
||||
docs: $(srcdir)/$(PACKAGE_NAME).1 $(srcdir)/web/ccache-man.html
|
||||
docs: $(srcdir)/$(PACKAGE_NAME).1 $(srcdir)/web/$(PACKAGE_NAME)-man.html
|
||||
|
||||
$(PACKAGE_NAME)$(EXEEXT): $(OBJS) $(HEADERS)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
|
||||
|
|
@ -40,40 +38,43 @@ $(PACKAGE_NAME)$(EXEEXT): $(OBJS) $(HEADERS)
|
|||
$(srcdir)/$(PACKAGE_NAME).1: $(srcdir)/ccache.yo
|
||||
-yodl2man -o $(srcdir)/$(PACKAGE_NAME).1 $(srcdir)/ccache.yo
|
||||
|
||||
$(srcdir)/web/ccache-man.html: $(srcdir)/ccache.yo
|
||||
yodl2html -o $(srcdir)/web/ccache-man.html $(srcdir)/ccache.yo
|
||||
$(srcdir)/web/$(PACKAGE_NAME)-man.html: $(srcdir)/ccache.yo
|
||||
yodl2html -o $(srcdir)/web/$(PACKAGE_NAME)-man.html $(srcdir)/ccache.yo
|
||||
|
||||
install: $(PACKAGE_NAME)$(EXEEXT)
|
||||
@echo "Installing $(PACKAGE_NAME)"
|
||||
@echo "Installing $(DESTDIR)${bindir}/`echo $(PACKAGE_NAME) | sed '$(transform)'`$(EXEEXT)"
|
||||
@echo "Installing $(DESTDIR)${bindir}/$(PROGRAM_NAME)$(EXEEXT)"
|
||||
${INSTALLCMD} -d $(DESTDIR)${bindir}
|
||||
${INSTALLCMD} -m 755 $(PACKAGE_NAME)$(EXEEXT) $(DESTDIR)${bindir}/`echo $(PACKAGE_NAME) | sed '$(transform)'`$(EXEEXT)
|
||||
${INSTALLCMD} -m 755 $(PACKAGE_NAME)$(EXEEXT) $(DESTDIR)${bindir}/$(PROGRAM_NAME)$(EXEEXT)
|
||||
|
||||
install-docs: $(srcdir)/$(PACKAGE_NAME).1
|
||||
@echo "Installing $(DESTDIR)${mandir}/man1/`echo $(PACKAGE_NAME) | sed '$(transform)'`.1"
|
||||
@echo "Installing $(DESTDIR)${mandir}/man1/$(PROGRAM_NAME).1"
|
||||
${INSTALLCMD} -d $(DESTDIR)${mandir}/man1
|
||||
${INSTALLCMD} -m 644 $(srcdir)/$(PACKAGE_NAME).1 $(DESTDIR)${mandir}/man1/`echo $(PACKAGE_NAME) | sed '$(transform)'`.1
|
||||
${INSTALLCMD} -m 644 $(srcdir)/$(PACKAGE_NAME).1 $(DESTDIR)${mandir}/man1/$(PROGRAM_NAME).1
|
||||
|
||||
uninstall: $(PACKAGE_NAME)$(EXEEXT)
|
||||
rm -f $(DESTDIR)${bindir}/`echo $(PACKAGE_NAME) | sed '$(transform)'`$(EXEEXT)
|
||||
rm -f $(DESTDIR)${bindir}/$(PROGRAM_NAME)$(EXEEXT)
|
||||
|
||||
uninstall-docs: $(srcdir)/$(PACKAGE_NAME).1
|
||||
rm -f $(DESTDIR)${mandir}/man1/`echo $(PACKAGE_NAME) | sed '$(transform)'`.1
|
||||
rm -f $(DESTDIR)${mandir}/man1/$(PROGRAM_NAME).1
|
||||
|
||||
clean:
|
||||
clean: clean-docs
|
||||
/bin/rm -f $(OBJS) *~ $(PACKAGE_NAME)$(EXEEXT)
|
||||
|
||||
clean-docs:
|
||||
rm -f $(srcdir)/$(PACKAGE_NAME).1 $(srcdir)/web/$(PACKAGE_NAME)-man.html
|
||||
|
||||
test: test.sh
|
||||
SWIG_LIB='$(SWIG_LIB)' PATH=../..:$$PATH SWIG='$(SWIG)' CC='$(CC)' NOSOFTLINKSTEST='$(NOSOFTLINKSTEST)' $(srcdir)/test.sh
|
||||
SWIG_LIB='$(SWIG_LIB)' PATH=../..:$$PATH SWIG='$(SWIG)' CC='$(CC)' NOSOFTLINKSTEST='$(NOSOFTLINKSTEST)' CCACHE='../$(PACKAGE_NAME)' CCACHE_PROG=$(PROGRAM_NAME) $(srcdir)/test.sh
|
||||
|
||||
check: test
|
||||
|
||||
distclean: clean
|
||||
/bin/rm -f Makefile config.h config.sub config.log build-stamp config.status ccache_swig_config.h
|
||||
/bin/rm -f Makefile config.h config.sub config.log build-stamp config.status ccache_swig_config.h config_win32.h
|
||||
/bin/rm -rf autom4te.cache
|
||||
|
||||
maintainer-clean: distclean
|
||||
/bin/rm -f $(srcdir)/$(PACKAGE_NAME).1 $(srcdir)/web/ccache-man.html
|
||||
/bin/rm -f $(srcdir)/$(PACKAGE_NAME).1 $(srcdir)/web/$(PACKAGE_NAME)-man.html
|
||||
|
||||
|
||||
# FIXME: To fix this, test.sh needs to be able to take ccache from the
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
#include "config.h"
|
||||
#else
|
||||
#include <sys/locking.h>
|
||||
#define PACKAGE_NAME "ccache-swig.exe"
|
||||
#include "config_win32.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
|
@ -51,7 +51,7 @@
|
|||
#define STATUS_FATAL 4
|
||||
#define STATUS_NOCACHE 5
|
||||
|
||||
#define MYNAME PACKAGE_NAME
|
||||
#define MYNAME PROGRAM_NAME
|
||||
|
||||
#define LIMIT_MULTIPLE 0.8
|
||||
|
||||
|
|
|
|||
3
CCache/config_win32.h.in
Normal file
3
CCache/config_win32.h.in
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
#if !defined(PROGRAM_NAME)
|
||||
#define PROGRAM_NAME "@PROGRAM_NAME@.exe"
|
||||
#endif
|
||||
|
|
@ -7,6 +7,7 @@ AC_CONFIG_SRCDIR([ccache.h])
|
|||
AC_MSG_NOTICE([Configuring ccache])
|
||||
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
AC_CONFIG_FILES([config_win32.h])
|
||||
|
||||
dnl Checks for programs.
|
||||
AC_PROG_CC
|
||||
|
|
@ -14,6 +15,20 @@ AC_PROG_CPP
|
|||
AC_PROG_INSTALL
|
||||
AC_ARG_PROGRAM # for program_transform_name
|
||||
|
||||
AC_SUBST(PROGRAM_NAME)
|
||||
if test "x$program_prefix" != "xNONE" -a "x$program_prefix" != "x"
|
||||
then
|
||||
PROGRAM_NAME="$program_prefix$PACKAGE_NAME"
|
||||
else
|
||||
PROGRAM_NAME="$PACKAGE_NAME"
|
||||
fi
|
||||
if test "x$program_suffix" != "xNONE" -a "x$program_suffix" != "x"
|
||||
then
|
||||
PROGRAM_NAME="$PROGRAM_NAME$program_suffix"
|
||||
fi
|
||||
|
||||
AC_DEFINE_UNQUOTED(PROGRAM_NAME, "$PROGRAM_NAME", [Define my program name])
|
||||
|
||||
AC_DEFINE([_GNU_SOURCE], 1,
|
||||
[Define _GNU_SOURCE so that we get all necessary prototypes])
|
||||
|
||||
|
|
|
|||
|
|
@ -292,6 +292,7 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args
|
|||
break;
|
||||
case 'X':
|
||||
flags |= DP_F_UP;
|
||||
/* FALLTHROUGH */
|
||||
case 'x':
|
||||
flags |= DP_F_UNSIGNED;
|
||||
if (cflags == DP_C_SHORT)
|
||||
|
|
@ -314,6 +315,7 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args
|
|||
break;
|
||||
case 'E':
|
||||
flags |= DP_F_UP;
|
||||
/* FALLTHROUGH */
|
||||
case 'e':
|
||||
if (cflags == DP_C_LDOUBLE)
|
||||
fvalue = va_arg (args, LDOUBLE);
|
||||
|
|
@ -322,6 +324,7 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args
|
|||
break;
|
||||
case 'G':
|
||||
flags |= DP_F_UP;
|
||||
/* FALLTHROUGH */
|
||||
case 'g':
|
||||
if (cflags == DP_C_LDOUBLE)
|
||||
fvalue = va_arg (args, LDOUBLE);
|
||||
|
|
|
|||
|
|
@ -20,7 +20,12 @@ fi
|
|||
PATH="`echo $PATH | \
|
||||
sed -e 's!:/usr\(/local\)*/lib\([0-9]\)*/ccache\(/\)*!!g'`"
|
||||
|
||||
CCACHE=../ccache-swig
|
||||
if test -n "$CCACHE"; then
|
||||
CCACHE="$CCACHE"
|
||||
else
|
||||
CCACHE=../ccache-swig
|
||||
fi
|
||||
|
||||
TESTDIR=test.$$
|
||||
|
||||
test_failed() {
|
||||
|
|
@ -406,6 +411,10 @@ swigtests() {
|
|||
# main program
|
||||
rm -rf $TESTDIR
|
||||
mkdir $TESTDIR
|
||||
if test -n "$CCACHE_PROG"; then
|
||||
ln -s $CCACHE $TESTDIR/$CCACHE_PROG
|
||||
CCACHE=./$CCACHE_PROG
|
||||
fi
|
||||
cd $TESTDIR || exit 1
|
||||
|
||||
unset CCACHE_DIR
|
||||
|
|
|
|||
4
CHANGES
4
CHANGES
|
|
@ -11813,7 +11813,7 @@ Version 1.3.23 (November 11, 2004)
|
|||
ie, no additional pointer elements are created, and
|
||||
the original 'foo' and 'A.bar' can be used as parameters.
|
||||
|
||||
In the case of member fucntion however, still you need
|
||||
In the case of member function however, still you need
|
||||
to use the special variable Class::<fnc_name>_cb_ptr, ie:
|
||||
|
||||
foobarm(3, a, A.barm_cb_ptr)
|
||||
|
|
@ -21116,7 +21116,7 @@ Version 1.3.7 (September 3, 2001)
|
|||
typedef __name vector<T>;
|
||||
%enddef
|
||||
|
||||
An a specific instantiation is created in exactly the same way:
|
||||
A specific instantiation is created in exactly the same way:
|
||||
|
||||
%template(intvec) vector<int>;
|
||||
|
||||
|
|
|
|||
625
CHANGES.current
625
CHANGES.current
|
|
@ -4,21 +4,630 @@ See the RELEASENOTES file for a summary of changes in each release.
|
|||
Issue # numbers mentioned below can be found on Github. For more details, add
|
||||
the issue number to the end of the URL: https://github.com/swig/swig/issues/
|
||||
|
||||
Version 3.0.13 (in progress)
|
||||
============================
|
||||
Version 4.0.0 (in progress)
|
||||
===========================
|
||||
|
||||
2018-04-18: olly
|
||||
[Python] Suppress new pycodestyle warning:
|
||||
E252 missing whitespace around parameter equals
|
||||
|
||||
2018-04-07: goatshriek
|
||||
[Ruby] #1213 Fix ruby %alias directive for global C/C++ functions.
|
||||
|
||||
2018-04-03: olly
|
||||
[Ruby] Fix to pass Qnil instead of NULL to rb_funcall(), which silences GCC
|
||||
-Wconversion-null warning (on by default with recent GCC).
|
||||
|
||||
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 platform inconsistency in Python default argument handling.
|
||||
32 bit and 64 bit compiled versions of SWIG generated different Python files
|
||||
when default arguments were outside the range of 32 bit signed integers.
|
||||
The default arguments specified in Python are now only those that are in the
|
||||
range of a 32 bit signed integer, otherwise the default is obtained from C/C++ code.
|
||||
|
||||
2017-10-02: wsfulton
|
||||
[C#] Fix std::complex types passed by value.
|
||||
|
||||
2017-10-02: wsfulton
|
||||
[Javascript, Python, Ruby] Issue #732 - Missing type information for std::complex
|
||||
in std_complex.i meant that previously std::complex always had to be fully qualified
|
||||
in order to be wrapped with the appropriate typemaps.
|
||||
|
||||
2017-10-01: joequant
|
||||
allow R package names with docs
|
||||
allowing mulitple get accessors in R
|
||||
fix smrt-pointer and NAMESPACE support
|
||||
constructors now returning smart pointers (if class
|
||||
declared as such)
|
||||
smart-pointer classes deriving from parent smart-pointers
|
||||
|
||||
2017-09-29: wsfulton
|
||||
Issue #1100 - Allow an instantiated template to have the same name in the target
|
||||
language as the C++ template name, for example, this is now possible:
|
||||
|
||||
template<typename T> struct X { ... };
|
||||
%template(X) X<int>;
|
||||
|
||||
2017-09-23: wsfulton
|
||||
Issue #1098. Fix overloading of shared_ptr with underlying pointer types, eg:
|
||||
|
||||
void m(std::shared_ptr<T> p);
|
||||
void m(T &p);
|
||||
void m(T *p);
|
||||
|
||||
Only the first method is wrapped and the others are ignored/shadowed.
|
||||
The implementation is done via a new attribute in the 'typecheck' typemap called
|
||||
'equivalent'. If specified, it must contain the equivalent pointer type for overloading
|
||||
and can only be used for the special SWIG_TYPECHECK_POINTER precedence level.
|
||||
The shared_ptr 'typecheck' typemaps have been modified accordingly.
|
||||
Here is a simplified version:
|
||||
|
||||
%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="T *")
|
||||
T,
|
||||
T CONST &,
|
||||
T CONST *,
|
||||
T *CONST&,
|
||||
std::shared_ptr< T >,
|
||||
std::shared_ptr< T > &,
|
||||
std::shared_ptr< T > *,
|
||||
std::shared_ptr< T > *&
|
||||
{ ... }
|
||||
|
||||
Overloading with any of these types will result in SWIG ignoring all but the first
|
||||
overloaded method by default. Without the 'equivalent' attribute, wrapping the overloaded
|
||||
methods resulted in types being shadowed (scripting languages) or code that did not
|
||||
compile (statically typed languages).
|
||||
|
||||
2017-09-19: futatuki
|
||||
[Python] #1003 Add --with-2to3=/path/to/2to3 option to configure.
|
||||
|
||||
2017-09-18: wsfulton
|
||||
Fix type promotion wrapping constant expressions of the form:
|
||||
# define EXPR_MIXED1 (0x80 + 11.1) - 1
|
||||
This was previously an integral type instead of a floating point type.
|
||||
|
||||
2017-09-17: wsfulton
|
||||
Fix generated code for constant expressions containing wchar_t L literals such as:
|
||||
# define __WCHAR_MAX (0x7fffffff + L'\0')
|
||||
# define __WCHAR_MIN (-__WCHAR_MAX - 1)
|
||||
|
||||
2017-09-10: mlamarre
|
||||
[Python] Patch #1083. Define_DEBUG to 1 to do exactly like Visual Studio
|
||||
/LDd, /MDd or /MTd compiler options.
|
||||
|
||||
2017-08-25: wsfulton
|
||||
Issue #1059. Add support for C++11 ref-qualifiers on non-static member functions.
|
||||
Members with lvalue ref-qualifiers such as:
|
||||
|
||||
struct RQ {
|
||||
void m1(int x) &;
|
||||
void m2(int x) const &;
|
||||
};
|
||||
|
||||
are wrapped like any other member function. Member functions with rvalue ref-qualifiers
|
||||
are ignored by default, such as:
|
||||
|
||||
struct RQ {
|
||||
void m3(int x) &&;
|
||||
void m4(int x) const &&;
|
||||
};
|
||||
|
||||
example.i:7: Warning 405: Method with rvalue ref-qualifier m3(int) && ignored.
|
||||
example.i:8: Warning 405: Method with rvalue ref-qualifier m4(int) const && ignored.
|
||||
|
||||
These can be unignored and exposed to the target language, see further documentation in
|
||||
CPlusPlus11.html.
|
||||
|
||||
2017-08-16: wsfulton
|
||||
Fix #1063. Add using declarations to templates into typedef table.
|
||||
|
||||
Using declarations to templates were missing in SWIG's internal typedef tables.
|
||||
This led to a few problems, such as, templates that did not instantiate and generated
|
||||
C++ code that did not compile as SWIG did not know what scope the template was
|
||||
in. This happened mostly when a using declaration was used on a template type in a
|
||||
completely unrelated namespace.
|
||||
|
||||
2017-08-16: wsfulton
|
||||
Fix type lookup in the presence of using directives and using declarations.
|
||||
|
||||
Fix some cases of type lookup failure via a combination of both using directives and
|
||||
using declarations resulting in C++ code that did not compile as the generated type was
|
||||
not fully qualified for use in the global namespace. Example below:
|
||||
|
||||
namespace Space5 {
|
||||
namespace SubSpace5 {
|
||||
namespace SubSubSpace5 {
|
||||
struct F {};
|
||||
}
|
||||
}
|
||||
using namespace SubSpace5;
|
||||
using SubSubSpace5::F;
|
||||
void func(SubSubSpace5::F f);
|
||||
}
|
||||
|
||||
2017-08-16: wsfulton
|
||||
Issue #1051. %template scope enforcement and class definition fixes.
|
||||
|
||||
The scoping rules around %template have been specified and enforced.
|
||||
The %template directive for a class template is the equivalent to an
|
||||
explicit instantiation of a C++ class template. The scope for a valid
|
||||
%template instantiation is now the same as the scope required for a
|
||||
valid explicit instantiation of a C++ template. A definition of the
|
||||
template for the explicit instantiation must be in scope where the
|
||||
instantiation is declared and must not be enclosed within a different
|
||||
namespace.
|
||||
|
||||
For example, a few %template and C++ explicit instantiations of std::vector
|
||||
are shown below:
|
||||
|
||||
// valid
|
||||
namespace std {
|
||||
%template(vin) vector<int>;
|
||||
template class vector<int>;
|
||||
}
|
||||
|
||||
// valid
|
||||
using namespace std;
|
||||
%template(vin) vector<int>;
|
||||
template class vector<int>;
|
||||
|
||||
// valid
|
||||
using std::vector;
|
||||
%template(vin) vector<int>;
|
||||
template class vector<int>;
|
||||
|
||||
// ill-formed
|
||||
namespace unrelated {
|
||||
using std::vector;
|
||||
%template(vin) vector<int>;
|
||||
template class vector<int>;
|
||||
}
|
||||
|
||||
// ill-formed
|
||||
namespace unrelated {
|
||||
using namespace std;
|
||||
%template(vin) vector<int>;
|
||||
template class vector<int>;
|
||||
}
|
||||
|
||||
// ill-formed
|
||||
namespace unrelated {
|
||||
namespace std {
|
||||
%template(vin) vector<int>;
|
||||
template class vector<int>;
|
||||
}
|
||||
}
|
||||
|
||||
// ill-formed
|
||||
namespace unrelated {
|
||||
%template(vin) std::vector<int>;
|
||||
template class std::vector<int>;
|
||||
}
|
||||
|
||||
When the scope is incorrect, an error now occurs such as:
|
||||
|
||||
cpp_template_scope.i:34: Error: 'vector' resolves to 'std::vector' and
|
||||
was incorrectly instantiated in scope 'unrelated' instead of within scope 'std'.
|
||||
|
||||
Previously SWIG accepted the ill-formed examples above but this led to
|
||||
numerous subtle template scope problems especially in the presence of
|
||||
using declarations and using directives as well as with %feature and %typemap.
|
||||
|
||||
Actually, a valid instantiation is one which conforms to the C++03
|
||||
standard as C++11 made a change to disallow using declarations and
|
||||
using directives to find a template.
|
||||
|
||||
// valid C++03, ill-formed C++11
|
||||
using std::vector;
|
||||
template class vector<int>;
|
||||
|
||||
Similar fixes for defining classes using forward class references have
|
||||
also been put in place. For example:
|
||||
|
||||
namespace Space1 {
|
||||
struct A;
|
||||
}
|
||||
namespace Space2 {
|
||||
struct Space1::A {
|
||||
void x();
|
||||
}
|
||||
}
|
||||
|
||||
will now error out with:
|
||||
|
||||
cpp_class_definition.i:5: Error: 'Space1::A' resolves to 'Space1::A' and
|
||||
was incorrectly instantiated in scope 'Space2' instead of within scope 'Space1'.
|
||||
|
||||
Previously some symbols would have been instantiated in the wrong scope and led
|
||||
to lots of scope problems involving SWIG typemaps, features, renames etc.
|
||||
You will need to correct the scope used in other SWIG directives which do not
|
||||
support 'using declarations' and 'using directives'. For example, if you previously had:
|
||||
|
||||
%rename(Zap) vector<int>::clear;
|
||||
using namespace std;
|
||||
%template(VectorInt) vector<int>;
|
||||
|
||||
Prior versions of SWIG incorrectly instantiated vector<int> in the global namespace
|
||||
and so the %rename matched. Now the template is instantiated in the correct namespace,
|
||||
so is fully qualified as std::vector<int>. The other SWIG directives need correcting as
|
||||
they do not follow 'using declarations' and 'using directives'. Change it to:
|
||||
|
||||
%rename(Zap) std::vector<int>::clear;
|
||||
using namespace std;
|
||||
%template(vin) vector<int>;
|
||||
|
||||
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
2017-08-16: wsfulton
|
||||
Fix scope lookup for template parameters containing unary scope operators.
|
||||
|
||||
Fixes cases like:
|
||||
|
||||
namespace Alloc {
|
||||
template<typename T> struct Rebind {
|
||||
typedef int Integer;
|
||||
};
|
||||
}
|
||||
%template(RebindBucket) Alloc::Rebind< Bucket >;
|
||||
OR
|
||||
%template(RebindBucket) Alloc::Rebind< ::Bucket >;
|
||||
|
||||
Alloc::Rebind< Bucket >::Integer Bucket1();
|
||||
Alloc::Rebind< ::Bucket >::Integer Bucket2();
|
||||
Alloc::Rebind<::template TemplateBucket<double>>::Integer Bucket3();
|
||||
|
||||
2017-08-16: wsfulton
|
||||
For templates only, the template parameters are fully resolved when
|
||||
handling typemaps. Without this, it is too hard to have decent rules
|
||||
to apply typemaps when parameter types are typedef'd and template
|
||||
parameters have default values.
|
||||
|
||||
Fixes %clear for typedefs in templates, eg:
|
||||
|
||||
%typemap("in") XXX<int>::Long "..."
|
||||
template typename<T> struct XXX {
|
||||
typedef long Long;
|
||||
};
|
||||
%clear XXX<int>::Long;
|
||||
|
||||
as the typemap was previously incorrectly stored as a typemap for long
|
||||
instead of XXX<int>::Long.
|
||||
|
||||
2017-08-05: olly
|
||||
[C++11] Allow static_assert at the top level (and disallow it right
|
||||
after template<T>). Fixes https://github.com/swig/swig/issues/1031
|
||||
reported by Artem V L.
|
||||
|
||||
2017-08-02: wsfulton
|
||||
Fix incorrectly shown warning when an empty template instantiation was used on a
|
||||
class used as a base class and that base class was explicitly ignored with %ignore.
|
||||
Example of the warning which will no longer appear:
|
||||
|
||||
Warning 401: Base class 'Functor< int,int >' has no name as it is an empty
|
||||
template instantiated with '%template()'. Ignored.
|
||||
|
||||
2017-07-17: fflexo
|
||||
[Java] #674 Add std_list.i to add support for std::list containers. The Java proxy
|
||||
extends java.util.AbstractSequentialList and makes the C++ std::list container look
|
||||
and feel much like a java.util.LinkedList from Java.
|
||||
|
||||
2017-07-07: wsfulton
|
||||
[Python] Fix display of documented template types when using the autodoc
|
||||
feature. For example when wrapping:
|
||||
|
||||
%feature("autodoc");
|
||||
template<typename X> struct T {};
|
||||
%template(TInteger) T<int>;
|
||||
|
||||
the generated documentation contains:
|
||||
"""Proxy of C++ T< int > class."""
|
||||
instead of:
|
||||
"""Proxy of C++ T<(int)> class."""
|
||||
and
|
||||
"""__init__(TInteger self) -> TInteger"""
|
||||
instead of
|
||||
"""__init__(T<(int)> self) -> TInteger"""
|
||||
|
||||
2017-06-27: nihaln
|
||||
[PHP] Update the OUTPUT Typemap to add return statement to the
|
||||
PHP Wrapper.
|
||||
|
||||
2017-06-27: nihaln
|
||||
[PHP] Update the enum and value examples to use the OO wrappers
|
||||
rather than the flat functions produced with -noproxy. There's
|
||||
not been a good reason to use -noproxy for since PHP5 OO wrapping
|
||||
was fixed back in 2005.
|
||||
|
||||
2017-06-23: m7thon
|
||||
[Python] fix and improve default argument handling:
|
||||
|
||||
1. Fix negative octals. Currently not handled correctly by `-py3`
|
||||
(unusual case, but incorrect).
|
||||
2. Fix arguments of type "octal + something" (e.g. `0640 | 04`).
|
||||
Currently drops everything after the first octal. Nasty!
|
||||
3. Fix bool arguments "0 + something" (e.g. `0 | 1`) are always
|
||||
"False" (unusual case, but incorrect).
|
||||
4. Remove special handling of "TRUE" and "FALSE" from
|
||||
`convertValue` since there's no reason these have to match
|
||||
"true" and "false".
|
||||
5. Remove the Python 2 vs. Python 3 distinction based on the
|
||||
`-py3` flag. Now the same python code is produced for default
|
||||
arguments for Python 2 and Python 3. For this, octal default
|
||||
arguments, e.g. 0644, are now wrapped as `int('644', 8)`. This
|
||||
is required, as Python 2 and Python 3 have incompatible syntax
|
||||
for octal literals.
|
||||
|
||||
Fixes #707
|
||||
|
||||
2017-06-21: futatuki
|
||||
#1004 - Fix ccache-swig executable name to respect configure's --program-prefix and
|
||||
--program-suffix values if used.
|
||||
|
||||
2017-06-21: tamuratak
|
||||
[Ruby] #911 - Add std::wstring support.
|
||||
|
||||
2017-06-19: wsfulton
|
||||
[Python] Fix handling of rich comparisons when wrapping overloaded operators:
|
||||
|
||||
operator< operator<= operator> operator>= operator== operator!=
|
||||
|
||||
Previously a TypeError was always thrown if the type was not correct. NotImplemented
|
||||
is now returned from these wrapped functions if the type being compared with is
|
||||
not correct. The subsequent behaviour varies between different versions of Python
|
||||
and the comparison function being used, but is now consistent with normal Python
|
||||
behaviour. For example, for the first 4 operator overloads above, a TypeError
|
||||
'unorderable types' is thrown in Python 3, but Python 2 will return True or False.
|
||||
NotImplemented should be returned when the comparison cannot be done, see PEP 207 and
|
||||
https://docs.python.org/3/library/constants.html#NotImplemented
|
||||
|
||||
Note that the bug was only present when overloaded operators did not also have a
|
||||
function overload.
|
||||
|
||||
Fixes SF bug #1208 (3441262) and SF patch #303.
|
||||
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
2017-06-17: fabrice102
|
||||
[Go] Fix Go callback example. Fixes github #600, #955, #1000.
|
||||
|
||||
2017-06-16: wsfulton
|
||||
Make sure warning and error messages are not split up by other processes writing to
|
||||
stdout at the same time.
|
||||
|
||||
2017-06-16: wsfulton
|
||||
[R] Fix wrapping function pointers containing rvalue and lvalue reference parameters.
|
||||
|
||||
2017-06-13: olly
|
||||
[Perl] Fix testsuite to work without . in @INC - it was removed in
|
||||
Perl 5.26 for security reasons, and has also been removed from
|
||||
older versions in some distros. Fixes
|
||||
https://github.com/swig/swig/issues/997 reported by lfam.
|
||||
|
||||
2017-06-03: wsfulton
|
||||
Fix %import on a file containing a file scope %fragment forced inclusion to not
|
||||
generate the fragment contents as %import should not result in code being generated.
|
||||
The behaviour is now the same as importing code insertion blocks.
|
||||
Wrapping FileC.i in the following example will result in no generated code, whereas
|
||||
previously "#include <limits.h>" was generated:
|
||||
|
||||
// FileA.i
|
||||
%fragment("<limits.h>", "header") %{
|
||||
#include <limits.h>
|
||||
%}
|
||||
|
||||
%{
|
||||
#include <stdio.h>
|
||||
%}
|
||||
%fragment("<limits.h>");
|
||||
|
||||
// FileC.i
|
||||
%import "FileA.i"
|
||||
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
2017-05-26: Volker Diels-Grabsch, vadz
|
||||
[Java] #842 Extend from java.util.AbstractList<> and implement java.util.RandomAccess for
|
||||
std::vector wrappers. This notably allows to iterate over wrapped vectors in a natural way.
|
||||
2017-05-30: davidcl
|
||||
[Scilab] #994 Undefined symbol error when loading in Scilab 6
|
||||
|
||||
2017-05-25: asibross
|
||||
[Java] #370 #417 Missing smart pointer handling in Java director extra methods
|
||||
swigReleaseOwnership() and swigTakeOwnership().
|
||||
|
||||
2017-05-23: wsfulton
|
||||
[Java] #230 #759 Fix Java shared_ptr and directors for derived classes java compilation
|
||||
error.
|
||||
|
||||
For shared_ptr proxy proxy classes, add a protected method swigSetCMemOwn for modifying
|
||||
the swigCMemOwn and swigCMemOwnDerived member variables which are used by various other
|
||||
methods for controlling memory ownership.
|
||||
|
||||
2017-05-21: Sghirate
|
||||
[Java, C#, D] #449 Remove unnecessary use of dynamic_cast in directors to enable
|
||||
non-RTTI compilation.
|
||||
|
||||
2017-05-21: wsfulton
|
||||
[Python] #993 Fix handling of default -ve unsigned values, such as:
|
||||
void f(unsigned = -1U);
|
||||
|
||||
2017-05-20: jschueller
|
||||
[Python] #991 Fix E731 PEP8 warning: do not assign a lambda expression
|
||||
|
||||
2017-05-16: nihal95
|
||||
[PHP] Add %pragma version directive to allow the version of the
|
||||
extension to be set. Patch #970, fixes #360.
|
||||
|
||||
2017-05-13: yag00
|
||||
Patch #975 - Add support for noexcept on director methods.
|
||||
|
||||
2017-04-27: redbrain
|
||||
Issue #974, Patch #976 - Fix preprocessor handling of macros with commas in a comment.
|
||||
|
||||
2017-04-25: jleveque
|
||||
[Lua] #959 - Fix Visual Studio C4244 conversion warnings in Lua wrappers.
|
||||
|
||||
2017-04-21: tamuratak
|
||||
[Ruby] #964 - Add shared_ptr director typemaps.
|
||||
|
||||
2017-04-20: wsfulton
|
||||
[Ruby] #586, #935 Add assert for invalid NULL type parameter when calling SWIG_Ruby_NewPointerObj.
|
||||
|
||||
2017-04-20: tamuratak
|
||||
[Ruby] #930, #937 - Fix containers of std::shared_ptr.
|
||||
Upcasting, const types (eg vector<shared_ptr<const T>>) and NULL/nullptr support added.
|
||||
|
||||
2017-04-12: smarchetto
|
||||
[Scilab] New parameter targetversion to specify the Scilab target version (5, 6, ..) for code generation
|
||||
With Scilab 6 target specified, identifier names truncation is disabled (no longer necessary)
|
||||
|
||||
2017-02-29: tamuratak
|
||||
[Ruby] #917 - Add Enumerable module to all container class wrappers. It was missing
|
||||
for std::list, std::multiset, std::unordered_multiset and std::unordered_map.
|
||||
|
||||
2017-03-24: tamuratak
|
||||
[Ruby] Fix #939 - Wrapping std::vector<bool> fix due to incorrect null checks
|
||||
on VALUE obj.
|
||||
|
||||
2017-03-17: vadz
|
||||
[C#] #947 Add support for std::complex<T>
|
||||
|
||||
2017-03-17: wsfulton
|
||||
[Go] Fix handling of typedef'd function pointers and typedef'd member function pointers
|
||||
such as:
|
||||
|
|
@ -43,6 +652,10 @@ Version 3.0.13 (in progress)
|
|||
auto sum1(int x, int y) const -> int { return x + y; }
|
||||
auto sum2(int x, int y) noexcept -> int { return x + y; }
|
||||
|
||||
2017-02-29: tamuratak
|
||||
[Ruby] #917 - Add Enumerable module to all container class wrappers. It was missing
|
||||
for std::list, std::multiset, std::unordered_multiset and std::unordered_map.
|
||||
|
||||
2017-02-27: assambar
|
||||
[C++11] Extend parser to support throw specifier in combination
|
||||
with override and/or final.
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@ SWIG directives. SWIG can be furnished with a header file, but an
|
|||
interface can also be generated without library headers by supplying a
|
||||
simple text file--called the interface file, which is typically named
|
||||
with a <tt>.i</tt> extension--containing any foreign declarations of
|
||||
identifiers you wish to use. The most common approach is to use a an
|
||||
identifiers you wish to use. The most common approach is to use an
|
||||
interface file with directives to parse the needed headers. A straight
|
||||
parse of library headers will result in usable code, but SWIG
|
||||
directives provides much freedom in how a user might tailor the
|
||||
|
|
|
|||
|
|
@ -409,7 +409,7 @@ All the steps required to compile and use a simple hierarchy of classes for shap
|
|||
|
||||
<p>
|
||||
First create an Android project called <tt>SwigClass</tt> in a subdirectory called <tt>class</tt>.
|
||||
The steps below create and build a the JNI C++ app.
|
||||
The steps below create and build the JNI C++ app.
|
||||
Adjust the <tt>--target</tt> id as mentioned earlier in the <a href="Android.html#Android_examples_intro">Examples introduction</a>.
|
||||
</p>
|
||||
|
||||
|
|
|
|||
|
|
@ -411,7 +411,7 @@ following conditions need to be met:
|
|||
|
||||
|
||||
<p>
|
||||
ccache was inspired by the compilercache shell script script written
|
||||
ccache was inspired by the compilercache shell script written
|
||||
by Erik Thiele and I would like to thank him for an excellent piece of
|
||||
work. See
|
||||
<a href="http://www.erikyyy.de/compilercache/">http://www.erikyyy.de/compilercache/</a>
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
<li><a href="#CPlusPlus11_noexcept">Exception specifications and noexcept</a>
|
||||
<li><a href="#CPlusPlus11_alignment">Control and query object alignment</a>
|
||||
<li><a href="#CPlusPlus11_attributes">Attributes</a>
|
||||
<li><a href="#CPlusPlus11_ref_qualifiers">Methods with ref-qualifiers</a>
|
||||
</ul>
|
||||
<li><a href="#CPlusPlus11_standard_library_changes">Standard library changes</a>
|
||||
<ul>
|
||||
|
|
@ -877,7 +878,8 @@ so in this case it is entirely possible to pass an int instead of a double to <t
|
|||
|
||||
|
||||
<p>
|
||||
SWIG correctly parses the new <tt>static_assert</tt> declarations.
|
||||
SWIG correctly parses the new <tt>static_assert</tt> declarations (though 3.0.12 and earlier
|
||||
had a bug which meant this wasn't accepted at file scope).
|
||||
This is a C++ compile time directive so there isn't anything useful that SWIG can do with it.
|
||||
</p>
|
||||
|
||||
|
|
@ -970,6 +972,104 @@ int [[attr1]] i [[attr2, attr3]];
|
|||
[[noreturn, nothrow]] void f [[noreturn]] ();
|
||||
</pre></div>
|
||||
|
||||
|
||||
<H3><a name="CPlusPlus11_ref_qualifiers">7.2.29 Methods with ref-qualifiers</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
C++11 non-static member functions can be declared with ref-qualifiers.
|
||||
Member functions declared with a <tt>&</tt> lvalue ref-qualifiers are wrapped like any other function without ref-qualifiers.
|
||||
Member functions declared with a <tt>&&</tt> rvalue ref-qualifiers are ignored by default
|
||||
as they are unlikely to be required from non-C++ languages where the concept of <i>rvalue-ness</i>
|
||||
for the implied *this pointer does not apply.
|
||||
The warning is hidden by default, but can be displayed as described in the section on <a href="Warnings.html#Warnings_nn4">Enabling extra warnings</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Consider:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
struct RQ {
|
||||
void m1(int x) &;
|
||||
void m2(int x) &&;
|
||||
};
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
The only wrapped method will be the lvalue ref-qualified method <tt>m1</tt>
|
||||
and if SWIG is run with the <tt>-Wextra</tt> command-line option, the following warning will be issued indicating <tt>m2</tt> is not wrapped:
|
||||
</p>
|
||||
|
||||
<div class="shell">
|
||||
<pre>
|
||||
example.i:7: Warning 405: Method with rvalue ref-qualifier m2(int) && ignored.
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
If you unignore the method as follows, wrappers for <tt>m2</tt> will be generated:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
%feature("ignore", "0") RQ::m2(int x) &&;
|
||||
struct RQ {
|
||||
void m1(int x) &;
|
||||
void m2(int x) &&;
|
||||
};
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
Inspection of the generated C++ code, will show that <tt>std::move</tt> is used on the instance
|
||||
of the <tt>RQ *</tt> class:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
RQ *arg1 = (RQ *) 0 ;
|
||||
int arg2 ;
|
||||
|
||||
arg1 = ...marshalled from target language...
|
||||
arg2 = ...marshalled from target language...
|
||||
|
||||
std::move(*arg1).m2(arg2);
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
This will compile but when run, the move effects may not be what you want.
|
||||
As stated earlier, rvalue ref-qualifiers aren't really applicable outside the world of C++.
|
||||
However, if you really know what you are doing, full control over the call to the method is
|
||||
possible via the low-level "action" feature.
|
||||
This feature completely replaces the call to the underlying function, that is, the last line in the snippet of code above.
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
%feature("ignore", "0") RQ::m2(int x) &&;
|
||||
%feature("action") RQ::m2(int x) && %{
|
||||
RQ().m2(arg2);
|
||||
%}
|
||||
struct RQ {
|
||||
void m1(int x) &;
|
||||
void m2(int x) &&;
|
||||
};
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
resulting in:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
RQ *arg1 = (RQ *) 0 ;
|
||||
int arg2 ;
|
||||
|
||||
arg1 = ...marshalled from target language...
|
||||
arg2 = ...marshalled from target language...
|
||||
|
||||
RQ().m2(arg2);
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
<b>Compatibility note:</b> SWIG-4.0.0 was the first version to support ref-qualifiers.
|
||||
</p>
|
||||
<H2><a name="CPlusPlus11_standard_library_changes">7.3 Standard library changes</a></H2>
|
||||
|
||||
|
||||
|
|
@ -1176,5 +1276,6 @@ Phew, that is a lot of hard work to get a callback working.
|
|||
You could just go with the more attractive option of just using <tt>double</tt> as the return type in the function declaration instead of <tt>result_of</tt>!
|
||||
</p>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -677,7 +677,7 @@ As a result, we get the following method in the module class:
|
|||
<div class="code">
|
||||
<pre>
|
||||
public static void myArrayCopy(int[] sourceArray, int[] targetArray, int nitems) {
|
||||
examplePINVOKE.myArrayCopy(sourceArray, targetArray, nitems);
|
||||
examplePINVOKE.myArrayCopy(sourceArray, targetArray, nitems);
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -997,9 +997,9 @@ When the following C# code is executed:
|
|||
<div class="code">
|
||||
<pre>
|
||||
public class runme {
|
||||
static void Main() {
|
||||
example.positivesonly(-1);
|
||||
}
|
||||
static void Main() {
|
||||
example.positivesonly(-1);
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1772,7 +1772,7 @@ should pass the call on to <tt>CSharpDefaults.DefaultMethod(int)</tt>using the C
|
|||
|
||||
|
||||
<p>
|
||||
When using <a href="Modules.html#Modules">multiple modules</a> it is is possible to compile each SWIG generated wrapper
|
||||
When using <a href="Modules.html#Modules">multiple modules</a> it is possible to compile each SWIG generated wrapper
|
||||
into a different assembly.
|
||||
However, by default the generated code may not compile if
|
||||
generated classes in one assembly use generated classes in another assembly.
|
||||
|
|
@ -1846,12 +1846,12 @@ and the following usage from C# after running the code through SWIG:
|
|||
|
||||
<div class="code">
|
||||
<pre>
|
||||
Wheel wheel = new Bike(10).getWheel();
|
||||
Console.WriteLine("wheel size: " + wheel.size);
|
||||
// Simulate a garbage collection
|
||||
global::System.GC.Collect();
|
||||
global::System.GC.WaitForPendingFinalizers();
|
||||
global::System.Console.WriteLine("wheel size: " + wheel.size);
|
||||
Wheel wheel = new Bike(10).getWheel();
|
||||
Console.WriteLine("wheel size: " + wheel.size);
|
||||
// Simulate a garbage collection
|
||||
global::System.GC.Collect();
|
||||
global::System.GC.WaitForPendingFinalizers();
|
||||
global::System.Console.WriteLine("wheel size: " + wheel.size);
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -1980,9 +1980,9 @@ and more or less equivalent usage from C#
|
|||
|
||||
<div class="code">
|
||||
<pre>
|
||||
Container container = new Container();
|
||||
Element element = new Element(20);
|
||||
container.setElement(element);
|
||||
Container container = new Container();
|
||||
Element element = new Element(20);
|
||||
container.setElement(element);
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -1993,14 +1993,14 @@ In order to understand why, consider a garbage collection occuring...
|
|||
|
||||
<div class="code">
|
||||
<pre>
|
||||
Container container = new Container();
|
||||
Element element = new Element(20);
|
||||
container.setElement(element);
|
||||
Console.WriteLine("element.value: " + container.getElement().value);
|
||||
// Simulate a garbage collection
|
||||
global::System.GC.Collect();
|
||||
global::System.GC.WaitForPendingFinalizers();
|
||||
global::System.Console.WriteLine("element.value: " + container.getElement().value);
|
||||
Container container = new Container();
|
||||
Element element = new Element(20);
|
||||
container.setElement(element);
|
||||
Console.WriteLine("element.value: " + container.getElement().value);
|
||||
// Simulate a garbage collection
|
||||
global::System.GC.Collect();
|
||||
global::System.GC.WaitForPendingFinalizers();
|
||||
global::System.Console.WriteLine("element.value: " + container.getElement().value);
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -2019,37 +2019,50 @@ public class Container : global::System.IDisposable {
|
|||
// Ensure that the GC doesn't collect any Element set from C#
|
||||
// as the underlying C++ class stores a shallow copy
|
||||
private Element elementReference;
|
||||
private global::System.Runtime.InteropServices.HandleRef getCPtrAndAddReference(Element element) {
|
||||
elementReference = element;
|
||||
return Element.getCPtr(element);
|
||||
}
|
||||
|
||||
public void setElement(Element e) {
|
||||
examplePINVOKE.Container_setElement(swigCPtr, getCPtrAndAddReference(e));
|
||||
examplePINVOKE.Container_setElement(swigCPtr, Element.getCPtr(e));
|
||||
elementReference = e;
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
The following typemaps will generate the desired code.
|
||||
The 'csin' typemap matches the input parameter type for the <tt>setElement</tt> method.
|
||||
The 'cscode' typemap simply adds in the specified code into the C# proxy class.
|
||||
The following typemaps can be used to generate this code:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%typemap(csin) Element *e "getCPtrAndAddReference($csinput)"
|
||||
|
||||
%typemap(cscode) Container %{
|
||||
// Ensure that the GC doesn't collect any Element set from C#
|
||||
// as the underlying C++ class stores a shallow copy
|
||||
private Element elementReference;
|
||||
private global::System.Runtime.InteropServices.HandleRef getCPtrAndAddReference(Element element) {
|
||||
elementReference = element;
|
||||
return Element.getCPtr(element);
|
||||
}
|
||||
%}
|
||||
|
||||
%typemap(csin,
|
||||
post=" elementReference = $csinput;"
|
||||
) Element *e "Element.getCPtr($csinput)"
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
The 'cscode' typemap simply adds in the specified code into the C# proxy class.
|
||||
The 'csin' typemap matches the input parameter type and name for the <tt>setElement</tt> method and
|
||||
the 'post' typemap attribute allows adding code after the PInvoke call.
|
||||
The 'post' code is generated into a finally block after the PInvoke call so the resulting code isn't quite
|
||||
as mentioned earlier, <tt>setElement</tt> is actually:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
public void setElement(Element e) {
|
||||
try {
|
||||
examplePINVOKE.Container_setElement(swigCPtr, Element.getCPtr(e));
|
||||
} finally {
|
||||
elementReference = e;
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -228,7 +228,6 @@
|
|||
<li><a href="SWIGPlus.html#SWIGPlus_nn12">Static members</a>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_member_data">Member data</a>
|
||||
</ul>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_default_args">Default arguments</a>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_nn15">Protection</a>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_nn16">Enums and constants</a>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_nn17">Friends</a>
|
||||
|
|
@ -236,16 +235,27 @@
|
|||
<li><a href="SWIGPlus.html#SWIGPlus_nn19">Pass and return by value</a>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_nn20">Inheritance</a>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_nn21">A brief discussion of multiple inheritance, pointers, and type checking</a>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_overloaded_methods">Wrapping Overloaded Functions and Methods</a>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_default_args">Default arguments</a>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_overloaded_methods">Overloaded functions and methods</a>
|
||||
<ul>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_nn24">Dispatch function generation</a>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_nn25">Ambiguity in Overloading</a>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_ambiguity_resolution_renaming">Ambiguity resolution and renaming</a>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_nn25">Ambiguity in overloading</a>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_ambiguity_resolution_renaming">Renaming and ambiguity resolution</a>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_nn27">Comments on overloading</a>
|
||||
</ul>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_nn28">Wrapping overloaded operators</a>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_nn28">Overloaded operators</a>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_class_extension">Class extension</a>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_nn30">Templates</a>
|
||||
<ul>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_template_directive">The %template directive</a>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_template_functions">Function templates</a>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_template_classes">Default template arguments</a>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_template_class_inheritance">Template base classes</a>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_template_specialization">Template specialization</a>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_template_member">Member templates</a>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_template_scoping">Scoping and templates</a>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_template_more">More on templates</a>
|
||||
</ul>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_namespaces">Namespaces</a>
|
||||
<ul>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_nspace">The nspace feature for namespaces</a>
|
||||
|
|
@ -259,6 +269,11 @@
|
|||
<li><a href="SWIGPlus.html#SWIGPlus_nn35">Using declarations and inheritance</a>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_nested_classes">Nested classes</a>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_const">A brief rant about const-correctness</a>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_target_language_callbacks">Callbacks to the target language</a>
|
||||
<ul>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_director_classes_introduction">Introduction to director classes</a>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_directors_for_function_pointers">Using directors and target language callbacks</a>
|
||||
</ul>
|
||||
<li><a href="SWIGPlus.html#SWIGPlus_nn42">Where to go for more information</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
@ -300,6 +315,7 @@
|
|||
<li><a href="CPlusPlus11.html#CPlusPlus11_noexcept">Exception specifications and noexcept</a>
|
||||
<li><a href="CPlusPlus11.html#CPlusPlus11_alignment">Control and query object alignment</a>
|
||||
<li><a href="CPlusPlus11.html#CPlusPlus11_attributes">Attributes</a>
|
||||
<li><a href="CPlusPlus11.html#CPlusPlus11_ref_qualifiers">Methods with ref-qualifiers</a>
|
||||
</ul>
|
||||
<li><a href="CPlusPlus11.html#CPlusPlus11_standard_library_changes">Standard library changes</a>
|
||||
<ul>
|
||||
|
|
@ -347,26 +363,33 @@
|
|||
<div class="sectiontoc">
|
||||
<ul>
|
||||
<li><a href="Library.html#Library_nn2">The %include directive and library search path</a>
|
||||
<li><a href="Library.html#Library_nn3">C Arrays and Pointers</a>
|
||||
<li><a href="Library.html#Library_nn3">C arrays and pointers</a>
|
||||
<ul>
|
||||
<li><a href="Library.html#Library_nn4">cpointer.i</a>
|
||||
<li><a href="Library.html#Library_carrays">carrays.i</a>
|
||||
<li><a href="Library.html#Library_nn6">cmalloc.i</a>
|
||||
<li><a href="Library.html#Library_nn7">cdata.i</a>
|
||||
</ul>
|
||||
<li><a href="Library.html#Library_nn8">C String Handling</a>
|
||||
<li><a href="Library.html#Library_nn8">C string handling</a>
|
||||
<ul>
|
||||
<li><a href="Library.html#Library_nn9">Default string handling</a>
|
||||
<li><a href="Library.html#Library_nn10">Passing binary data</a>
|
||||
<li><a href="Library.html#Library_nn11">Using %newobject to release memory</a>
|
||||
<li><a href="Library.html#Library_nn12">cstring.i</a>
|
||||
</ul>
|
||||
<li><a href="Library.html#Library_stl_cpp_library">STL/C++ Library</a>
|
||||
<li><a href="Library.html#Library_stl_cpp_library">STL/C++ library</a>
|
||||
<ul>
|
||||
<li><a href="Library.html#Library_std_string">std::string</a>
|
||||
<li><a href="Library.html#Library_std_vector">std::vector</a>
|
||||
<li><a href="Library.html#Library_stl_exceptions">STL exceptions</a>
|
||||
<li><a href="Library.html#Library_std_shared_ptr">shared_ptr smart pointer</a>
|
||||
<ul>
|
||||
<li><a href="Library.html#Library_shared_ptr_basics">shared_ptr basics</a>
|
||||
<li><a href="Library.html#Library_shared_ptr_inheritance">shared_ptr and inheritance</a>
|
||||
<li><a href="Library.html#Library_shared_ptr_overloading">shared_ptr and method overloading</a>
|
||||
<li><a href="Library.html#Library_shared_ptr_templates">shared_ptr and templates</a>
|
||||
<li><a href="Library.html#Library_shared_ptr_directors">shared_ptr and directors</a>
|
||||
</ul>
|
||||
<li><a href="Library.html#Library_std_auto_ptr">auto_ptr smart pointer</a>
|
||||
</ul>
|
||||
<li><a href="Library.html#Library_nn16">Utility Libraries</a>
|
||||
|
|
@ -461,7 +484,7 @@
|
|||
<li><a href="Typemaps.html#Typemaps_nn35">"memberin" typemap</a>
|
||||
<li><a href="Typemaps.html#Typemaps_nn36">"varin" typemap</a>
|
||||
<li><a href="Typemaps.html#Typemaps_nn37">"varout" typemap</a>
|
||||
<li><a href="Typemaps.html#throws_typemap">"throws" typemap</a>
|
||||
<li><a href="Typemaps.html#Typemaps_throws_typemap">"throws" typemap</a>
|
||||
</ul>
|
||||
<li><a href="Typemaps.html#Typemaps_nn39">Some typemap examples</a>
|
||||
<ul>
|
||||
|
|
@ -483,6 +506,9 @@
|
|||
<li><a href="Typemaps.html#Typemaps_runtime_type_checker_usage">Usage</a>
|
||||
</ul>
|
||||
<li><a href="Typemaps.html#Typemaps_overloading">Typemaps and overloading</a>
|
||||
<ul>
|
||||
<li><a href="Typemaps.html#Typemaps_typecheck_pointer">SWIG_TYPECHECK_POINTER precedence level and the typecheck typemap</a>
|
||||
</ul>
|
||||
<li><a href="Typemaps.html#Typemaps_nn48">More about %apply and %clear</a>
|
||||
<li><a href="Typemaps.html#Typemaps_nn47">Passing data between typemaps</a>
|
||||
<li><a href="Typemaps.html#Typemaps_nn52">C++ "this" pointer</a>
|
||||
|
|
@ -1010,6 +1036,9 @@
|
|||
<li><a href="Java.html#Java_directors_threading">Director threading issues</a>
|
||||
<li><a href="Java.html#Java_directors_performance">Director performance tuning</a>
|
||||
<li><a href="Java.html#Java_exceptions_from_directors">Java exceptions from directors</a>
|
||||
<ul>
|
||||
<li><a href="Java.html#Java_customizing_director_exceptions">Customizing director exceptions</a>
|
||||
</ul>
|
||||
</ul>
|
||||
<li><a href="Java.html#Java_allprotected">Accessing protected members</a>
|
||||
<li><a href="Java.html#Java_common_customization">Common customization features</a>
|
||||
|
|
|
|||
|
|
@ -356,7 +356,7 @@ In this case, the exception handler is only attached to declarations
|
|||
named "allocate". This would include both global and member
|
||||
functions. The names supplied to <tt>%exception</tt> follow the same
|
||||
rules as for <tt>%rename</tt> described in the section on
|
||||
<a href="SWIGPlus.html#SWIGPlus_ambiguity_resolution_renaming">Ambiguity resolution and renaming</a>.
|
||||
<a href="SWIGPlus.html#SWIGPlus_ambiguity_resolution_renaming">Renaming and ambiguity resolution</a>.
|
||||
For example, if you wanted to define
|
||||
an exception handler for a specific class, you might write this:
|
||||
</p>
|
||||
|
|
@ -516,7 +516,7 @@ The special variables are often used in situations where method calls are logged
|
|||
$action
|
||||
}
|
||||
catch (MemoryError) {
|
||||
croak("Out of memory in $decl");
|
||||
croak("Out of memory in $decl");
|
||||
}
|
||||
}
|
||||
void log(const char *message);
|
||||
|
|
@ -796,7 +796,7 @@ involving <tt>%feature</tt>:
|
|||
</div>
|
||||
|
||||
<p>
|
||||
The name matching rules outlined in the <a href="SWIGPlus.html#SWIGPlus_ambiguity_resolution_renaming">Ambiguity resolution and renaming</a>
|
||||
The name matching rules outlined in the <a href="SWIGPlus.html#SWIGPlus_ambiguity_resolution_renaming">Renaming and ambiguity resolution</a>
|
||||
section applies to all <tt>%feature</tt> directives.
|
||||
In fact the <tt>%rename</tt> directive is just a special form of <tt>%feature</tt>.
|
||||
The matching rules mean that features are very flexible and can be applied with
|
||||
|
|
|
|||
|
|
@ -280,7 +280,7 @@ class SomeClass : AnInterface, AnotherInterface {
|
|||
...
|
||||
}
|
||||
</pre></div>
|
||||
<p>For this to work, <tt>AnInterface</tt> and <tt>AnotherInterface</tt> have to be in scope. If SWIG is not in split proxy mode, this is already the case, but it it is, they have to be added to the import list via the <tt>dimports</tt> typemap. Additionally, the import statement depends on the package SWIG is configured to emit the modules to.</p>
|
||||
<p>For this to work, <tt>AnInterface</tt> and <tt>AnotherInterface</tt> have to be in scope. If SWIG is not in split proxy mode, this is already the case, but if it is, they have to be added to the import list via the <tt>dimports</tt> typemap. Additionally, the import statement depends on the package SWIG is configured to emit the modules to.</p>
|
||||
<p>The <tt>$importtype</tt> macro helps you to elegantly solve this problem:</p>
|
||||
<div class="code"><pre>
|
||||
%typemap(dimports) RemoteMpe %{
|
||||
|
|
|
|||
|
|
@ -1576,7 +1576,7 @@ return the node for the first class member.
|
|||
|
||||
<div class="indent">
|
||||
Returns the last child node. You might use this if you wanted to append a new
|
||||
node to the of a class.
|
||||
node to the children of a class.
|
||||
</div>
|
||||
|
||||
<p>
|
||||
|
|
@ -2592,36 +2592,36 @@ command line options, simply use code similar to this:
|
|||
<pre>
|
||||
void Language::main(int argc, char *argv[]) {
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (argv[i]) {
|
||||
if (strcmp(argv[i], "-interface") == 0) {
|
||||
if (argv[i+1]) {
|
||||
interface = NewString(argv[i+1]);
|
||||
Swig_mark_arg(i);
|
||||
Swig_mark_arg(i+1);
|
||||
i++;
|
||||
} else {
|
||||
Swig_arg_error();
|
||||
}
|
||||
} else if (strcmp(argv[i], "-globals") == 0) {
|
||||
if (argv[i+1]) {
|
||||
global_name = NewString(argv[i+1]);
|
||||
Swig_mark_arg(i);
|
||||
Swig_mark_arg(i+1);
|
||||
i++;
|
||||
} else {
|
||||
Swig_arg_error();
|
||||
}
|
||||
} else if ((strcmp(argv[i], "-proxy") == 0)) {
|
||||
proxy_flag = 1;
|
||||
Swig_mark_arg(i);
|
||||
} else if (strcmp(argv[i], "-keyword") == 0) {
|
||||
use_kw = 1;
|
||||
Swig_mark_arg(i);
|
||||
} else if (strcmp(argv[i], "-help") == 0) {
|
||||
fputs(usage, stderr);
|
||||
}
|
||||
...
|
||||
if (argv[i]) {
|
||||
if (strcmp(argv[i], "-interface") == 0) {
|
||||
if (argv[i+1]) {
|
||||
interface = NewString(argv[i+1]);
|
||||
Swig_mark_arg(i);
|
||||
Swig_mark_arg(i+1);
|
||||
i++;
|
||||
} else {
|
||||
Swig_arg_error();
|
||||
}
|
||||
} else if (strcmp(argv[i], "-globals") == 0) {
|
||||
if (argv[i+1]) {
|
||||
global_name = NewString(argv[i+1]);
|
||||
Swig_mark_arg(i);
|
||||
Swig_mark_arg(i+1);
|
||||
i++;
|
||||
} else {
|
||||
Swig_arg_error();
|
||||
}
|
||||
} else if ((strcmp(argv[i], "-proxy") == 0)) {
|
||||
proxy_flag = 1;
|
||||
Swig_mark_arg(i);
|
||||
} else if (strcmp(argv[i], "-keyword") == 0) {
|
||||
use_kw = 1;
|
||||
Swig_mark_arg(i);
|
||||
} else if (strcmp(argv[i], "-help") == 0) {
|
||||
fputs(usage, stderr);
|
||||
}
|
||||
...
|
||||
}
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
|
|
@ -3164,7 +3164,7 @@ these kinds of problems.
|
|||
</p>
|
||||
|
||||
<dt> <b>Examples/Makefile.in</b>
|
||||
<dd> Nothing special here; see comments at top the of this file
|
||||
<dd> Nothing special here; see comments at the top of this file
|
||||
and look to the existing languages for examples.
|
||||
|
||||
<dt> <b>Examples/qux99/check.list</b>
|
||||
|
|
|
|||
|
|
@ -639,12 +639,12 @@ public:
|
|||
virtual ~FooBarAbstract() {};
|
||||
|
||||
std::string FooBar() {
|
||||
return this->Foo() + ", " + this->Bar();
|
||||
return this->Foo() + ", " + this->Bar();
|
||||
};
|
||||
|
||||
protected:
|
||||
virtual std::string Foo() {
|
||||
return "Foo";
|
||||
return "Foo";
|
||||
};
|
||||
|
||||
virtual std::string Bar() = 0;
|
||||
|
|
|
|||
|
|
@ -94,6 +94,9 @@
|
|||
<li><a href="#Java_directors_threading">Director threading issues</a>
|
||||
<li><a href="#Java_directors_performance">Director performance tuning</a>
|
||||
<li><a href="#Java_exceptions_from_directors">Java exceptions from directors</a>
|
||||
<ul>
|
||||
<li><a href="#Java_customizing_director_exceptions">Customizing director exceptions</a>
|
||||
</ul>
|
||||
</ul>
|
||||
<li><a href="#Java_allprotected">Accessing protected members</a>
|
||||
<li><a href="#Java_common_customization">Common customization features</a>
|
||||
|
|
@ -3746,12 +3749,10 @@ Naturally, the SWIG generated C++ code and the generated Java intermediary class
|
|||
|
||||
<div class="code">
|
||||
<pre>
|
||||
public class DirectorDerived extends DirectorBase {
|
||||
public DirectorDerived() {
|
||||
}
|
||||
|
||||
class DirectorDerived extends DirectorBase {
|
||||
@Override
|
||||
public void upcall_method() {
|
||||
System.out.println("DirectorDerived::upcall_method() invoked.");
|
||||
System.out.println("DirectorDerived.upcall_method() invoked.");
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
|
|
@ -3774,7 +3775,7 @@ will result in the following being output:
|
|||
|
||||
<div class="code">
|
||||
<pre>
|
||||
DirectorDerived::upcall_method() invoked.
|
||||
DirectorDerived.upcall_method() invoked.
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -3825,45 +3826,186 @@ The disadvantage is that invocation of director methods from C++ when Java doesn
|
|||
<p>
|
||||
With directors routing method calls to Java, and proxies routing them
|
||||
to C++, the handling of exceptions is an important concern.
|
||||
The default behavior from SWIG 3.0
|
||||
onwards is to convert the thrown Java exception into a SWIG defined
|
||||
<code>DirectorException</code> C++ exception.
|
||||
SWIG 2.0 and earlier versions didn't provide any mechanism to handle the Java director method exceptions in C++.
|
||||
The default behavior for Java exceptions thrown in a director method overridden in Java is
|
||||
to store the thrown Java exception into a SWIG defined
|
||||
<code>Swig::DirectorException</code> C++ class exception in the C++ layer and then throw this C++ exception.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Converting Java exceptions into C++ exceptions can be done in two different ways using
|
||||
the <code>director:except</code> <a href="Customization.html#Customization_features">feature</a>.
|
||||
In the simplest approach, a code block is attached to each director method to
|
||||
handle the mapping of Java exceptions into C++ exceptions.
|
||||
Of course, should this exception be thrown, your C++ code must catch it and handle it before returning back to Java.
|
||||
The default generated code <b>does not</b> attempt to handle the C++ exception, but there is a simple way
|
||||
to make this all work by catching the C++ exception and extracting the original Java exception by using <tt>%catches</tt> for <tt>Swig::DirectorException</tt>.
|
||||
Consider the example shown earlier with a modification to the <tt>upcall_method</tt> Java method to throw a Java exception:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%feature("director:except") MyClass::method(int x) {
|
||||
jthrowable $error = jenv->ExceptionOccurred();
|
||||
if ($error) {
|
||||
jenv->ExceptionClear();
|
||||
if (Swig::ExceptionMatches(jenv, $error, "java/lang/IndexOutOfBoundsException"))
|
||||
throw std::out_of_range(Swig::JavaExceptionMessage(jenv, $error).message());
|
||||
if (Swig::ExceptionMatches(jenv, $error, "$packagepath/MyJavaException"))
|
||||
throw MyCppException(Swig::JavaExceptionMessage(jenv, $error).message());
|
||||
throw std::runtime_error("Unexpected exception thrown in MyClass::method");
|
||||
class DirectorDerived extends DirectorBase {
|
||||
@Override
|
||||
public void upcall_method() {
|
||||
System.out.println("DirectorDerived.upcall_method() invoked.");
|
||||
throw new RuntimeException("There was a problem!");
|
||||
}
|
||||
}
|
||||
|
||||
class MyClass {
|
||||
/** Throws either a std::out_of_range or MyCppException on error */
|
||||
void method(int x);
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
This approach allows a flexible mapping of Java exceptions thrown by director methods into
|
||||
C++ exceptions expected by a C++ caller. There
|
||||
need not be any C++ <em>exception specifications</em> on the C++ method. The
|
||||
utility function <code>Swig::ExceptionMatches</code>
|
||||
Now, by default, the JVM will abort when <tt>example.callup(director)</tt> is called as the C++
|
||||
<tt>Swig::DirectorException</tt> (storing the Java exception) is thrown and not handled by the <tt>callup</tt> method.
|
||||
Needless to say this is not very user friendly and so the recommendation is to add the following
|
||||
simple <tt>%catches</tt> directive before SWIG parses the <tt>callup</tt> function:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%catches(Swig::DirectorException) callup;
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Or target all wrapped methods using:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%catches(Swig::DirectorException);
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
This tells SWIG to generate a C++ catch handler using some code from the <a href="Typemaps.html#Typemaps_throws_typemap">throws typemap</a> for <tt>Swig::DirectorException</tt> that SWIG supplies by default, see <a href="SWIGPlus.html#SWIGPlus_catches">Exception handling with %catches</a>.
|
||||
This typemap code is written to simply catch the C++ <tt>Swig::DirectorException</tt> class and immediately
|
||||
return to Java throwing the original Java exception that it has stored.
|
||||
The net result is a stack trace containing the original Java exception including the location that the exception was thown from.
|
||||
</p>
|
||||
|
||||
<div class="shell">
|
||||
<pre>
|
||||
DirectorDerived.upcall_method() invoked.
|
||||
Exception in thread "main" java.lang.RuntimeException: There was a problem!
|
||||
at DirectorDerived.upcall_method(runme.java:4)
|
||||
at exampleJNI.SwigDirector_DirectorBase_upcall_method(exampleJNI.java:20)
|
||||
at exampleJNI.callup(Native Method)
|
||||
at example.callup(example.java:12)
|
||||
at runme.main(runme.java:21)
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
More on the <tt>Swig::DirectorException</tt> class can be found in the next section which details how to customize the handling of director exceptions.
|
||||
</p>
|
||||
|
||||
<H4><a name="Java_customizing_director_exceptions">25.5.7.1 Customizing director exceptions</a></H4>
|
||||
|
||||
|
||||
<p>
|
||||
This section is for advanced customization of director exceptions.
|
||||
The recommendation for most users is to use the simple <tt>%catches</tt> directive described above as it should be sufficient for most users needs.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The conversion of Java exceptions into C++ exceptions can be customized in two different ways using
|
||||
the <code>director:except</code> <a href="Customization.html#Customization_features">feature</a>.
|
||||
In the first approach, a code block is attached to each director method to
|
||||
handle the mapping of Java exceptions into C++ exceptions.
|
||||
The code block is generated just after the call up from the C++ director method into the overloaded method in Java. Its primary function is to check if a Java exception has been thrown and then handle it in C++.
|
||||
The example below converts a
|
||||
<tt>java.lang.IndexOutOfBoundsException</tt> into a C++ <tt>std::out_of_range</tt> exception and converts a
|
||||
user's Java <tt>MyJavaException</tt> into a C++ <tt>MyCppException</tt> exception.
|
||||
If the Java exception doesn't match either of these, a fallback <tt>std::runtime_error</tt> C++ exception is thrown.
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%feature("director:except") MyClass::dirmethod(int x) {
|
||||
jthrowable $error = jenv->ExceptionOccurred();
|
||||
if ($error) {
|
||||
if (Swig::ExceptionMatches(jenv, $error, "java/lang/IndexOutOfBoundsException"))
|
||||
throw std::out_of_range(Swig::JavaExceptionMessage(jenv, $error).message());
|
||||
if (Swig::ExceptionMatches(jenv, $error, "$packagepath/MyJavaException"))
|
||||
throw MyCppException(Swig::JavaExceptionMessage(jenv, $error).message());
|
||||
throw std::runtime_error("Unexpected exception thrown in MyClass::dirmethod");
|
||||
}
|
||||
}
|
||||
|
||||
class MyClass {
|
||||
public:
|
||||
/** Throws either a std::out_of_range or MyCppException on error */
|
||||
virtual void dirmethod(int x);
|
||||
virtual ~MyClass();
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
A few special variables are expanded within the <tt>director:except</tt> feature.
|
||||
</p>
|
||||
<ul>
|
||||
<li> The special variable <tt>$error</tt> is expanded into a unique variable name (swigerror)
|
||||
and should be used for the assignment of the jthrowable exception that occurred.</li>
|
||||
<li> The special variable <tt>$packagepath</tt> is
|
||||
replaced by the outer package provided for SWIG generation by the -package option. </li>
|
||||
<li> The special variable <tt>$directorthrowshandlers</tt> is not shown above, but is replaced
|
||||
by applicable "directorthrows" typemap contents (covered later in this section). </li>
|
||||
<li> The special variable <tt>$null</tt> is not shown above, but is replaced
|
||||
by a suitable default constructed object for returning from the director method (or nothing if
|
||||
the director method has a void return).
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
Utility functions/classes in director.swg are provided to aid the exception conversion as follows:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
namespace Swig {
|
||||
|
||||
// Helper method to determine if a Java throwable matches a particular Java class type
|
||||
// Note side effect of clearing any pending exceptions
|
||||
bool ExceptionMatches(JNIEnv *jenv, jthrowable throwable, const char *classname);
|
||||
|
||||
// Helper class to extract the exception message from a Java throwable
|
||||
class JavaExceptionMessage {
|
||||
public:
|
||||
JavaExceptionMessage(JNIEnv *jenv, jthrowable throwable);
|
||||
|
||||
// Return a C string of the exception message in the jthrowable passed in the constructor
|
||||
// If no message is available, null_string is return instead
|
||||
const char *message(const char *null_string =
|
||||
"Could not get exception message in JavaExceptionMessage") const;
|
||||
};
|
||||
|
||||
// C++ Exception class for handling Java exceptions thrown during a director method Java upcall
|
||||
class DirectorException : public std::exception {
|
||||
public:
|
||||
|
||||
// Construct exception from a Java throwable
|
||||
DirectorException(JNIEnv *jenv, jthrowable throwable);
|
||||
|
||||
// More general constructor for handling as a java.lang.RuntimeException
|
||||
DirectorException(const char *msg);
|
||||
|
||||
// Return exception message extracted from the Java throwable
|
||||
const char *what() const throw();
|
||||
|
||||
// Reconstruct and raise/throw the Java Exception that caused the DirectorException
|
||||
// Note that any error in the JNI exception handling results in a Java RuntimeException
|
||||
void throwException(JNIEnv *jenv) const;
|
||||
|
||||
// Create and throw the DirectorException
|
||||
static void raise(JNIEnv *jenv, jthrowable throwable) {
|
||||
throw DirectorException(jenv, throwable);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
The utility function <code>Swig::ExceptionMatches</code>
|
||||
and class <code>Swig::JavaExceptionMessage</code> are provided to simplify
|
||||
writing code for wrappers that use the <code>director:except</code> feature. The
|
||||
function <code>Swig::ExceptionMatches</code> matches the type of the
|
||||
|
|
@ -3871,13 +4013,10 @@ function <code>Swig::ExceptionMatches</code> matches the type of the
|
|||
name, such as <code>"java/lang/IOError"</code>. If the throwable class is the same
|
||||
type, or derives from the given type, <code>Swig::ExceptionMatches</code> will return true. Care must be taken to
|
||||
provide the correct fully qualified name, since for wrapped exceptions the
|
||||
generated proxy class will have additional package qualification, depending on
|
||||
generated proxy class will have an additional package qualification, depending on
|
||||
the '-package' argument and use of the <a href="#Java_namespaces">nspace
|
||||
feature</a>. The special variable <code>$error</code> is expanded by SWIG into a unique variable name and
|
||||
should be used for the
|
||||
assignment of the exception that occurred. The special variable <code>$packagepath</code> is
|
||||
replaced by the outer package provided for SWIG generation by the -package
|
||||
option. The utility class <code>Swig::JavaExceptionMessage</code> is a holder
|
||||
feature</a>.
|
||||
The utility class <code>Swig::JavaExceptionMessage</code> is a holder
|
||||
providing access to the message from the thrown Java exception.
|
||||
The <code>message()</code> method returns the exception message as a <code>const char *</code>,
|
||||
which is only valid during the lifetime of the holder. Any code using this message
|
||||
|
|
@ -3885,20 +4024,27 @@ needs to copy it, for example into a std::string or a newly constructed C++ exce
|
|||
</p>
|
||||
|
||||
<p>
|
||||
Using the above approach to
|
||||
Using the first approach above to
|
||||
write handlers for a large number of methods will require
|
||||
repetitive duplication of the <code>director:except</code> feature code.
|
||||
To mitigate this, an alternative approach is provided via typemaps in a
|
||||
repetitive duplication of the <code>director:except</code> feature code
|
||||
for each director method.
|
||||
To mitigate this, a second approach is provided via typemaps in a
|
||||
fashion analagous to
|
||||
the <a href="Typemaps.html#throws_typemap">"throws" typemap.</a> The
|
||||
"throws" typemap provides an approach to automatically map all the C++
|
||||
the <a href="Typemaps.html#throws_typemap">"throws" typemap</a>.
|
||||
The "throws" typemap provides a way to map all the C++
|
||||
exceptions listed in a method's defined exceptions (either from
|
||||
a C++ <em>exception specification</em> or a <code>%catches</code>
|
||||
feature) into Java exceptions.
|
||||
The "directorthrows" typemap provides the inverse mapping and should contain
|
||||
code to convert a suitably matching Java exception into a C++ exception.
|
||||
Only use this typemap if you wish to write custom conversions of Java exceptions into C++ exceptions
|
||||
and apply them to many different methods.
|
||||
The default handling which uses the <code>Swig::DirectorException</code> class should otherwise meet your needs.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The example below converts a Java <code>java.lang.IndexOutOfBoundsException</code> exception
|
||||
to the typemap's type, that is <code>std::out_of_range</code>:
|
||||
to the typemap's type, that is a <code>std::out_of_range</code> C++ exception:
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
|
|
@ -3913,7 +4059,7 @@ to the typemap's type, that is <code>std::out_of_range</code>:
|
|||
<p>
|
||||
The "directorthrows" typemap is then used in conjunction with the
|
||||
<code>director:except</code> feature if the <code>$directorthrowshandlers</code> special variable
|
||||
is used in the feature code. Consider the following, which also happens to be the default:
|
||||
is used in the code block. Consider the following, which also happens to be the default:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
|
|
@ -3921,31 +4067,41 @@ is used in the feature code. Consider the following, which also happens to be th
|
|||
%feature("director:except") %{
|
||||
jthrowable $error = jenv->ExceptionOccurred();
|
||||
if ($error) {
|
||||
jenv->ExceptionClear();
|
||||
$directorthrowshandlers
|
||||
throw Swig::DirectorException(jenv, $error);
|
||||
Swig::DirectorException::raise(jenv, $error);
|
||||
}
|
||||
%}
|
||||
</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
|
||||
<p>
|
||||
where <tt>Swig::DirectorException::raise</tt> is the helper method to throw a C++ <tt>Swig::DirectorException</tt>, see above.
|
||||
The code generated from the <code>director:except</code> feature
|
||||
has the <code>$directorthrowshandlers</code> special variable replaced with the code in
|
||||
the relevant "directorthrows" typemaps, for each and every exception defined for the method.
|
||||
The relevant exceptions can be defined either with a C++ exception
|
||||
specification or <code>%catches</code> as described for the
|
||||
<a href="Typemaps.html#throws_typemap">"throws" typemap</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Consider the following director method:
|
||||
Let's try and put all this together by considering the following director method:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
...
|
||||
struct X {
|
||||
virtual void doSomething(int index) throw (std::out_of_range);
|
||||
...
|
||||
};
|
||||
|
||||
OR
|
||||
|
||||
%catches(std::out_of_range) X::doSomething;
|
||||
struct X {
|
||||
virtual void doSomething(int index);
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -3958,12 +4114,10 @@ the resulting code generated in the director method after calling up to Java wil
|
|||
<pre>
|
||||
jthrowable swigerror = jenv->ExceptionOccurred();
|
||||
if (swigerror) {
|
||||
jenv->ExceptionClear();
|
||||
if (Swig::ExceptionMatches(jenv, swigerror, "java/lang/IndexOutOfBoundsException")) {
|
||||
throw std::out_of_range(Swig::JavaExceptionMessage(jenv, swigerror).message());
|
||||
}
|
||||
|
||||
throw Swig::DirectorException(jenv, swigerror);
|
||||
Swig::DirectorException::raise(jenv, swigerror);
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3971,7 +4125,7 @@ if (swigerror) {
|
|||
<p><em>
|
||||
Note: Beware of using exception specifications as the SWIG director methods
|
||||
will be generated with the same exception specifications and if the
|
||||
director method throws an exception that is not specified it is likely
|
||||
director method throws an exception that is not specified in the exception specifications list it is likely
|
||||
to terminate your program. See the C++ standard for more details.
|
||||
Using the %catches feature instead to define the handled exceptions does not suffer
|
||||
this potential fate.
|
||||
|
|
@ -3979,8 +4133,9 @@ this potential fate.
|
|||
|
||||
<p>Because the default code generation maps any unhandled Java exceptions to
|
||||
<code>Swig::DirectorException</code>, any director methods that have exception
|
||||
specifications may cause program termination. To simply ignore
|
||||
unexpected exceptions, the default handling can be changed with:
|
||||
specifications may cause program termination as this exception class won't be in the exception specifications list.
|
||||
You can avoid throwing <tt>Swig::DirectorException</tt> by changing the default handling for all methods by adding a <tt>director:except</tt> feature without any method name.
|
||||
For example, you can just ignore them:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
|
|
@ -3988,8 +4143,8 @@ unexpected exceptions, the default handling can be changed with:
|
|||
%feature("director:except") %{
|
||||
jthrowable $error = jenv->ExceptionOccurred();
|
||||
if ($error) {
|
||||
jenv->ExceptionClear();
|
||||
$directorthrowshandlers
|
||||
jenv->ExceptionClear();
|
||||
return $null; // exception is ignored
|
||||
}
|
||||
%}
|
||||
|
|
@ -3999,7 +4154,7 @@ unexpected exceptions, the default handling can be changed with:
|
|||
<p>Alternatively an exception compatible with the existing director
|
||||
method exception specifications can be thrown. Assuming that all
|
||||
methods allow std::runtime_error to be thrown,
|
||||
the <code>return $null;</code> could be changed to:
|
||||
the <code>return $null</code> line above could be changed to:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
|
|
@ -4009,124 +4164,296 @@ the <code>return $null;</code> could be changed to:
|
|||
</div>
|
||||
|
||||
<p>In more complex situations, a separate <code>director:except</code> feature
|
||||
may need to be attached to specific methods.
|
||||
may need to be attached to specific methods by providing a method name to the <tt>director:except</tt> feature.
|
||||
</p>
|
||||
|
||||
<p>Below is a complete example demonstrating the use
|
||||
of the "directorthrows" typemaps. In this example, a
|
||||
generic "directorthrows" typemap is appropriate for all three exceptions - all
|
||||
take single string constructors. If the exceptions had different constructors,
|
||||
it would be necessary to have separate typemaps for each exception type.
|
||||
<p>This is all no doubt quite hard to follow without seeing a full example and some code.
|
||||
Below is a complete example demonstrating the use
|
||||
of most of the exception customizations one can use, that is,
|
||||
"directorthrows" and "throws" typemaps, %exception and %catches.
|
||||
See the <a href="#Java_exception_handling">Exception handling with %exception and %javaexception</a>
|
||||
section for more on converting C++ exceptions to Java exceptions.
|
||||
The example also has a user defined C++ exception class called <tt>MyNS::MyException</tt> and this is wrapped as a Java exception.
|
||||
The director class being wrapped is <tt>MyClass</tt> and the director method is called <tt>MyClass::dirmethod</tt>.
|
||||
A number of <tt>std::cout</tt> calls have been added to help understand code flow.
|
||||
You can copy the code below into an interface file and run SWIG on it and examine the generated code.
|
||||
|
||||
|
||||
<!-- All the DEFINE_ and DECLARE_EXCEPTIONS CAN BE OMITTED to make
|
||||
this more succinct. They are included to make this a complete
|
||||
example interface that could be generated and built. -->
|
||||
<div class="code">
|
||||
<pre>
|
||||
%module(directors="1") example
|
||||
|
||||
%{
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
%}
|
||||
|
||||
// Define exceptions in header section using std::runtime_error
|
||||
%define DEFINE_EXCEPTION(NAME)
|
||||
%{
|
||||
namespace MyNS {
|
||||
struct NAME : public std::runtime_error { NAME(const std::string &what) : runtime_error(what) {} };
|
||||
// Generic catch handler for all wrapped methods
|
||||
%exception %{
|
||||
try {
|
||||
$action
|
||||
} 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()
|
||||
%define DECLARE_EXCEPTION(NAME)
|
||||
%typemap(javabase) MyNS::NAME "java.lang.Exception";
|
||||
%rename(getMessage) MyNS::NAME::what;
|
||||
// Expose C++ exception as a Java Exception by changing the Java base class and providing a getMessage()
|
||||
%typemap(javabase) MyNS::MyException "java.lang.RuntimeException";
|
||||
%rename(getMessage) MyNS::MyException::whatsup;
|
||||
|
||||
%inline %{
|
||||
namespace MyNS {
|
||||
struct NAME {
|
||||
NAME(const std::string& what);
|
||||
const char * what();
|
||||
class MyException {
|
||||
std::string msg;
|
||||
public:
|
||||
MyException(const char *msg) : msg(msg) {}
|
||||
const char * whatsup() const { return msg.c_str(); }
|
||||
};
|
||||
}
|
||||
%enddef
|
||||
|
||||
DEFINE_EXCEPTION(ExceptionA)
|
||||
DEFINE_EXCEPTION(ExceptionB)
|
||||
DEFINE_EXCEPTION(Unexpected)
|
||||
|
||||
// Mark three methods to map director thrown exceptions.
|
||||
%feature("director:except") MyClass::meth1(int);
|
||||
%feature("director:except") MyClass::meth2;
|
||||
%feature("director:except") meth3;
|
||||
|
||||
%typemap(directorthrows) MyNS::ExceptionA, MyNS::ExceptionB, MyNS::Unexpected %{
|
||||
if (Swig::ExceptionMatches(jenv, $error, "$packagepath/$javaclassname"))
|
||||
throw $1_type(Swig::JavaExceptionMessage(jenv, $error).message());
|
||||
%}
|
||||
|
||||
DECLARE_EXCEPTION(ExceptionA)
|
||||
DECLARE_EXCEPTION(ExceptionB)
|
||||
DECLARE_EXCEPTION(Unexpected)
|
||||
%typemap(directorthrows) MyNS::MyException %{
|
||||
if (Swig::ExceptionMatches(jenv, $error, "$packagepath/MyException")) {
|
||||
std::cout << "$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 {
|
||||
class MyClass {
|
||||
public:
|
||||
virtual void meth1(int x) throw(MyNS::ExceptionA, MyNS::ExceptionB) = 0;
|
||||
virtual void meth2() = 0; /* throws MyNS::ExceptionA, MyNS::ExceptionB, MyNS::Unexpected */
|
||||
virtual void meth3(float x) throw(MyNS::Unexpected) = 0;
|
||||
virtual ~MyClass() {}
|
||||
};
|
||||
// These are the exceptions that the director method MyClass::dirmethod will have catch handlers for.
|
||||
// Note that this is also a virtual method / director method and the C++ exceptions listed can be
|
||||
// thrown after converting them from Java exceptions.
|
||||
%catches(MyNS::MyException, Swig::DirectorException) MyClass::dirmethod;
|
||||
|
||||
// These are the exceptions that call_dirmethod C++ wrapper will have catch handlers for.
|
||||
// Note that this is not a virtual method, hence not a director method.
|
||||
%catches(MyNS::MyException, Swig::DirectorException) call_dirmethod;
|
||||
|
||||
%feature("director") MyClass;
|
||||
|
||||
%feature("director:except") MyClass::dirmethod(int x) {
|
||||
jthrowable $error = jenv->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 {
|
||||
public:
|
||||
/** Throws either a std::out_of_range or MyException on error */
|
||||
virtual void dirmethod(int x) {
|
||||
if (x <= 0)
|
||||
throw std::out_of_range("MyClass::dirmethod index is out of range");
|
||||
else if (x == 1)
|
||||
throw MyNS::MyException("MyClass::dirmethod some problem!");
|
||||
}
|
||||
virtual ~MyClass() {}
|
||||
static void call_dirmethod(MyClass& c, int x) {
|
||||
return c.dirmethod(x);
|
||||
}
|
||||
};
|
||||
%}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
In this case the three different "directorthrows" typemaps will be used
|
||||
to generate the three different exception handlers for
|
||||
<code>meth1</code>, <code>meth2</code> and <code>meth3</code>. The generated
|
||||
handlers will have "if" blocks for each exception type specified, in
|
||||
the exception specification or <code>%catches</code> feature.
|
||||
</p>
|
||||
|
||||
<p>Note that the "directorthrows" typemaps are important
|
||||
only if it is important for the the exceptions passed through the C++
|
||||
layer to be mapped to distinct C++ exceptions. If director methods
|
||||
are being called by C++ code that is itself wrapped in a
|
||||
SWIG generated Java wrapper and access is always through this wrapper,
|
||||
the default <code>Swig::DirectorException</code> class provides enough information
|
||||
to reconstruct the original exception. In this case removing the
|
||||
<code>$directorthrowshandlers</code> special variable from the
|
||||
default <code>director:except</code> feature and simply always
|
||||
throwing a <code>Swig::DirectorException</code> will achieve the desired result.
|
||||
Along with this a generic exception feature is added to convert any
|
||||
caught <code>Swig::DirectorException</code>s back into the underlying
|
||||
Java exceptions via the <code>Swig::DirectorException::raiseJavaException</code> method,
|
||||
as demonstrated with <code>%javaexception</code> below:
|
||||
The generated code for the <tt>call_dirmethod</tt> wrapper contains the various exception handlers.
|
||||
The outer exception handler is from the <tt>%exception</tt> directive and the others
|
||||
are from the "throws" typemaps.
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%javaexception("Exception") MyClass::myMethod %{
|
||||
SWIGEXPORT void JNICALL Java_exampleJNI_MyClass_1call_1dirmethod(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2) {
|
||||
...
|
||||
try {
|
||||
$action
|
||||
} catch (Swig::DirectorException &e) {
|
||||
// raise/throw the Java exception that originally caused the DirectorException
|
||||
e.raiseJavaException(jenv);
|
||||
return $null;
|
||||
try {
|
||||
MyClass::call_dirmethod(*arg1,arg2);
|
||||
} catch(MyNS::MyException &_e) {
|
||||
std::cout << "MyNS::MyException caught (throws typemap)" << std::endl;
|
||||
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>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
See the <a href="#Java_exception_handling">Exception handling with %exception and %javaexception</a>
|
||||
section for more on converting C++ exceptions to Java exceptions.
|
||||
The director method calling up to Java contains the exception handling code from the "directorthrows" typemaps and <tt>director:except</tt> feature.
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
void SwigDirector_MyClass::dirmethod(int x) {
|
||||
... [call up to Java using CallStaticVoidMethod]
|
||||
jthrowable swigerror = jenv->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>
|
||||
|
||||
|
||||
|
|
@ -4323,16 +4650,16 @@ struct Vector {
|
|||
|
||||
%extend Vector {
|
||||
char *toString() {
|
||||
static char tmp[1024];
|
||||
sprintf(tmp, "Vector(%g, %g, %g)", $self->x, $self->y, $self->z);
|
||||
return tmp;
|
||||
static char tmp[1024];
|
||||
sprintf(tmp, "Vector(%g, %g, %g)", $self->x, $self->y, $self->z);
|
||||
return tmp;
|
||||
}
|
||||
Vector(double x, double y, double z) {
|
||||
Vector *v = (Vector *) malloc(sizeof(Vector));
|
||||
v->x = x;
|
||||
v->y = y;
|
||||
v->z = z;
|
||||
return v;
|
||||
Vector *v = (Vector *) malloc(sizeof(Vector));
|
||||
v->x = x;
|
||||
v->y = y;
|
||||
v->z = z;
|
||||
return v;
|
||||
}
|
||||
};
|
||||
</pre>
|
||||
|
|
@ -5266,7 +5593,7 @@ void * operator new(size_t t) {
|
|||
throw bad_alloc();
|
||||
pJalloc->ref = 0;
|
||||
return static_cast<void *>(
|
||||
static_cast<char *>(static_cast<void *>(pJalloc)) + sizeof(Jalloc));
|
||||
static_cast<char *>(static_cast<void *>(pJalloc)) + sizeof(Jalloc));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -5681,6 +6008,17 @@ The most important of these implement the mapping of C/C++ types to Java types:
|
|||
In other words the typemap provides the conversion from the native method call return type. </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>jboxtype</td>
|
||||
<td>Java boxed type.
|
||||
These are Java code typemaps to provide the Java boxed type, such as, <tt>Integer</tt> for C type <tt>int</tt>.
|
||||
As autoboxing is only relevant to the Java primitive types, these are only provided for the
|
||||
C types that map to Java primitive types.
|
||||
This typemap is usually only used by C++ STL container wrappers that are wrapped by Java generic
|
||||
types as the boxed type must be used instead of the unboxed/primitive type when declaring a Java generic type.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>javadirectorin</td>
|
||||
<td>Conversion from jtype to jstype for director methods.
|
||||
|
|
@ -7217,7 +7555,7 @@ public class runme {
|
|||
example.print_args(animals);
|
||||
String args[] = example.get_args();
|
||||
for (int i=0; i<args.length; i++)
|
||||
System.out.println(i + ":" + args[i]);
|
||||
System.out.println(i + ":" + args[i]);
|
||||
}
|
||||
}
|
||||
</pre></div>
|
||||
|
|
@ -8142,40 +8480,52 @@ public class Container {
|
|||
// Ensure that the GC doesn't collect any Element set from Java
|
||||
// as the underlying C++ class stores a shallow copy
|
||||
private Element elementReference;
|
||||
private long getCPtrAndAddReference(Element element) {
|
||||
elementReference = element;
|
||||
return Element.getCPtr(element);
|
||||
}
|
||||
|
||||
public void setElement(Element e) {
|
||||
exampleJNI.Container_setElement(swigCPtr, this, getCPtrAndAddReference(e), e);
|
||||
exampleJNI.Container_setElement(swigCPtr, this, Element.getCPtr(e), e);
|
||||
elementReference = e;
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
The following typemaps will generate the desired code.
|
||||
The 'javain' typemap matches the input parameter type for the <tt>setElement</tt> method.
|
||||
The 'javacode' typemap simply adds in the specified code into the Java proxy class.
|
||||
The following typemaps can be used to generate this code:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%typemap(javain) Element *e "getCPtrAndAddReference($javainput)"
|
||||
|
||||
%typemap(javacode) Container %{
|
||||
// Ensure that the GC doesn't collect any element set from Java
|
||||
// as the underlying C++ class stores a shallow copy
|
||||
private Element elementReference;
|
||||
private long getCPtrAndAddReference(Element element) {
|
||||
elementReference = element;
|
||||
return Element.getCPtr(element);
|
||||
}
|
||||
%}
|
||||
|
||||
%typemap(javain,
|
||||
post=" elementReference = $javainput;"
|
||||
) Element *e "Element.getCPtr($javainput)"
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
The 'javacode' typemap simply adds in the specified code into the Java proxy class.
|
||||
The 'javain' typemap matches the input parameter type and name for the <tt>setElement</tt> method and
|
||||
the 'post' typemap attribute allows adding code after the JNI call.
|
||||
The 'post' code is generated into a finally block after the JNI call so the resulting code isn't quite
|
||||
as mentioned earlier, <tt>setElement</tt> is actually:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
public void setElement(Element e) {
|
||||
try {
|
||||
exampleJNI.Container_setElement(swigCPtr, this, Element.getCPtr(e), e);
|
||||
} finally {
|
||||
elementReference = e;
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<H3><a name="Java_date_marshalling">25.10.13 Date marshalling using the javain typemap and associated attributes</a></H3>
|
||||
|
||||
|
|
|
|||
|
|
@ -12,26 +12,33 @@
|
|||
<div class="sectiontoc">
|
||||
<ul>
|
||||
<li><a href="#Library_nn2">The %include directive and library search path</a>
|
||||
<li><a href="#Library_nn3">C Arrays and Pointers</a>
|
||||
<li><a href="#Library_nn3">C arrays and pointers</a>
|
||||
<ul>
|
||||
<li><a href="#Library_nn4">cpointer.i</a>
|
||||
<li><a href="#Library_carrays">carrays.i</a>
|
||||
<li><a href="#Library_nn6">cmalloc.i</a>
|
||||
<li><a href="#Library_nn7">cdata.i</a>
|
||||
</ul>
|
||||
<li><a href="#Library_nn8">C String Handling</a>
|
||||
<li><a href="#Library_nn8">C string handling</a>
|
||||
<ul>
|
||||
<li><a href="#Library_nn9">Default string handling</a>
|
||||
<li><a href="#Library_nn10">Passing binary data</a>
|
||||
<li><a href="#Library_nn11">Using %newobject to release memory</a>
|
||||
<li><a href="#Library_nn12">cstring.i</a>
|
||||
</ul>
|
||||
<li><a href="#Library_stl_cpp_library">STL/C++ Library</a>
|
||||
<li><a href="#Library_stl_cpp_library">STL/C++ library</a>
|
||||
<ul>
|
||||
<li><a href="#Library_std_string">std::string</a>
|
||||
<li><a href="#Library_std_vector">std::vector</a>
|
||||
<li><a href="#Library_stl_exceptions">STL exceptions</a>
|
||||
<li><a href="#Library_std_shared_ptr">shared_ptr smart pointer</a>
|
||||
<ul>
|
||||
<li><a href="#Library_shared_ptr_basics">shared_ptr basics</a>
|
||||
<li><a href="#Library_shared_ptr_inheritance">shared_ptr and inheritance</a>
|
||||
<li><a href="#Library_shared_ptr_overloading">shared_ptr and method overloading</a>
|
||||
<li><a href="#Library_shared_ptr_templates">shared_ptr and templates</a>
|
||||
<li><a href="#Library_shared_ptr_directors">shared_ptr and directors</a>
|
||||
</ul>
|
||||
<li><a href="#Library_std_auto_ptr">auto_ptr smart pointer</a>
|
||||
</ul>
|
||||
<li><a href="#Library_nn16">Utility Libraries</a>
|
||||
|
|
@ -92,7 +99,7 @@ Set the environment variable to hold an alternative library directory.
|
|||
The directories that are searched are displayed when using <tt>-verbose</tt> commandline option.
|
||||
</p>
|
||||
|
||||
<H2><a name="Library_nn3">9.2 C Arrays and Pointers</a></H2>
|
||||
<H2><a name="Library_nn3">9.2 C arrays and pointers</a></H2>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -411,13 +418,13 @@ void print_array(double x[10]);
|
|||
Now, in a scripting language, you might write this:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<div class="targetlang">
|
||||
<pre>
|
||||
a = new_doubleArray(10) # Create an array
|
||||
a = new_doubleArray(10) # Create an array
|
||||
for i in range(0, 10):
|
||||
doubleArray_setitem(a, i, 2*i) # Set a value
|
||||
print_array(a) # Pass to C
|
||||
delete_doubleArray(a) # Destroy array
|
||||
doubleArray_setitem(a, i, 2 * i) # Set a value
|
||||
print_array(a) # Pass to C
|
||||
delete_doubleArray(a) # Destroy array
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -475,12 +482,12 @@ void print_array(double x[10]);
|
|||
Allows you to do this:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<div class="targetlang">
|
||||
<pre>
|
||||
import example
|
||||
c = example.doubleArray(10) # Create double[10]
|
||||
for i in range(0, 10):
|
||||
c[i] = 2*i # Assign values
|
||||
c[i] = 2 * i # Assign values
|
||||
example.print_array(c) # Pass to C
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -496,6 +503,7 @@ you should consider using a special array object rather than a bare pointer.
|
|||
<p>
|
||||
<b>Note:</b> <tt>%array_functions()</tt> and <tt>%array_class()</tt> should not be
|
||||
used with types of <tt>char</tt> or <tt>char *</tt>.
|
||||
SWIG's default handling of these types is to handle them as character strings and the two macros do not do enough to change this.
|
||||
</p>
|
||||
|
||||
<H3><a name="Library_nn6">9.2.3 cmalloc.i</a></H3>
|
||||
|
|
@ -761,7 +769,7 @@ char *cdata_<em>name</em>(type* ptr, int nitems)
|
|||
Clearly they are unsafe.
|
||||
</p>
|
||||
|
||||
<H2><a name="Library_nn8">9.3 C String Handling</a></H2>
|
||||
<H2><a name="Library_nn8">9.3 C string handling</a></H2>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -801,7 +809,7 @@ target language. In other words, if you were using a language like Tcl,
|
|||
and you wrote this,
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<div class="targetlang">
|
||||
<pre>
|
||||
% foo Hello
|
||||
</pre>
|
||||
|
|
@ -852,7 +860,7 @@ size_t parity(char *str, size_t len, size_t initial);
|
|||
Now, in the target language, you can use binary string data like this:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<div class="targetlang">
|
||||
<pre>
|
||||
>>> s = "H\x00\x15eg\x09\x20"
|
||||
>>> parity(s, 0)
|
||||
|
|
@ -1365,7 +1373,7 @@ structure or class instead.
|
|||
</li>
|
||||
</ul>
|
||||
|
||||
<H2><a name="Library_stl_cpp_library">9.4 STL/C++ Library</a></H2>
|
||||
<H2><a name="Library_stl_cpp_library">9.4 STL/C++ library</a></H2>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -1385,16 +1393,24 @@ The following table shows which C++ classes are supported and the equivalent SWI
|
|||
<td><b>SWIG Interface library file</b></td>
|
||||
</tr>
|
||||
|
||||
<tr> <td>std::array (C++11)</td> <td>array</td> <td>std_array.i</td> </tr>
|
||||
<tr> <td>std::auto_ptr</td> <td>memory</td> <td>std_auto_ptr.i</td> </tr>
|
||||
<tr> <td>std::complex</td> <td>complex</td> <td>std_complex.i</td> </tr>
|
||||
<tr> <td>std::deque</td> <td>deque</td> <td>std_deque.i</td> </tr>
|
||||
<tr> <td>std::list</td> <td>list</td> <td>std_list.i</td> </tr>
|
||||
<tr> <td>std::map</td> <td>map</td> <td>std_map.i</td> </tr>
|
||||
<tr> <td>std::multimap (C++11)</td> <td>multimap</td> <td>std_multimap.i</td> </tr>
|
||||
<tr> <td>std::multiset (C++11)</td> <td>multiset</td> <td>std_multiset.i</td> </tr>
|
||||
<tr> <td>std::pair</td> <td>utility</td> <td>std_pair.i</td> </tr>
|
||||
<tr> <td>std::set</td> <td>set</td> <td>std_set.i</td> </tr>
|
||||
<tr> <td>std::string</td> <td>string</td> <td>std_string.i</td> </tr>
|
||||
<tr> <td>std::unordered_map (C++11)</td> <td>unordered_map</td> <td>std_unordered_map.i</td> </tr>
|
||||
<tr> <td>std::unordered_multimap (C++11)</td> <td>unordered_multimap</td> <td>std_unordered_multimap.i</td> </tr>
|
||||
<tr> <td>std::unordered_multiset (C++11)</td> <td>unordered_multiset</td> <td>std_unordered_multiset.i</td> </tr>
|
||||
<tr> <td>std::unordered_set (C++11)</td> <td>unordered_set</td> <td>std_unordered_set.i</td> </tr>
|
||||
<tr> <td>std::vector</td> <td>vector</td> <td>std_vector.i</td> </tr>
|
||||
<tr> <td>std::array</td> <td>array (C++11)</td> <td>std_array.i</td> </tr>
|
||||
<tr> <td>std::shared_ptr</td> <td>shared_ptr (C++11)</td> <td>std_shared_ptr.i</td> </tr>
|
||||
<tr> <td>std::wstring</td> <td>wstring</td> <td>std_wstring.i</td> </tr>
|
||||
<tr> <td>std::shared_ptr (C++11)</td> <td>shared_ptr</td> <td>std_shared_ptr.i</td> </tr>
|
||||
|
||||
</table>
|
||||
|
||||
|
|
@ -1460,7 +1476,7 @@ In the target language:
|
|||
<div class="targetlang">
|
||||
<pre>
|
||||
x = my_struct();
|
||||
x.foo="Hello World"; # assign with string
|
||||
x.foo = "Hello World"; # assign with string
|
||||
print x.foo; # print as string
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1720,6 +1736,9 @@ Any thrown STL exceptions will then be gracefully handled instead of causing a c
|
|||
<H3><a name="Library_std_shared_ptr">9.4.4 shared_ptr smart pointer</a></H3>
|
||||
|
||||
|
||||
<H4><a name="Library_shared_ptr_basics">9.4.4.1 shared_ptr basics</a></H4>
|
||||
|
||||
|
||||
<p>
|
||||
Some target languages have support for handling the shared_ptr reference counted smart pointer.
|
||||
This smart pointer is available in the standard C++11 library as <tt>std::shared_ptr</tt>.
|
||||
|
|
@ -1813,8 +1832,11 @@ System.out.println(val1 + " " + val2);
|
|||
</pre>
|
||||
</div>
|
||||
|
||||
<H4><a name="Library_shared_ptr_inheritance">9.4.4.2 shared_ptr and inheritance</a></H4>
|
||||
|
||||
|
||||
<p>
|
||||
This shared_ptr library works quite differently to SWIG's normal, but somewhat limited,
|
||||
The shared_ptr library works quite differently to SWIG's normal, but somewhat limited,
|
||||
<a href="SWIGPlus.html#SWIGPlus_smart_pointers">smart pointer handling</a>.
|
||||
The shared_ptr library does not generate extra wrappers, just for smart pointer handling, in addition to the proxy class.
|
||||
The normal proxy class including inheritance relationships is generated as usual.
|
||||
|
|
@ -1892,7 +1914,7 @@ Adding the missing <tt>%shared_ptr</tt> macros will fix this:
|
|||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%include "boost_shared_ptr.i"
|
||||
%include <boost_shared_ptr.i>
|
||||
%shared_ptr(GrandParent);
|
||||
%shared_ptr(Parent);
|
||||
%shared_ptr(Child);
|
||||
|
|
@ -1901,10 +1923,75 @@ Adding the missing <tt>%shared_ptr</tt> macros will fix this:
|
|||
</pre>
|
||||
</div>
|
||||
|
||||
<H4><a name="Library_shared_ptr_overloading">9.4.4.3 shared_ptr and method overloading</a></H4>
|
||||
|
||||
|
||||
<p>
|
||||
<b>Note:</b> There is somewhat limited support for <tt>%shared_ptr</tt> and the director feature
|
||||
and the degrees of success varies among the different target languages.
|
||||
Please help to improve this support by providing patches with improvements.
|
||||
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>
|
||||
The <tt>%shared_ptr</tt> macro should be used for all the required instantiations
|
||||
of the template before each of the <tt>%template</tt> instantiations.
|
||||
For example, consider <tt>number.h</tt> containing the following illustrative template:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
#include <memory>
|
||||
|
||||
template<int N> struct Number {
|
||||
int num;
|
||||
Number() : num(N) {}
|
||||
static std::shared_ptr<Number<N>> make() { return std::make_shared<Number<N>>(); }
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
The SWIG code below shows the required ordering:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%include <std_shared_ptr.i>
|
||||
|
||||
%shared_ptr(Number<10>);
|
||||
%shared_ptr(Number<42>);
|
||||
|
||||
%{
|
||||
#include "number.h"
|
||||
%}
|
||||
%include "number.h"
|
||||
|
||||
%template(Number10) Number<10>;
|
||||
%template(Number42) Number<42>;
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<H4><a name="Library_shared_ptr_directors">9.4.4.5 shared_ptr and directors</a></H4>
|
||||
|
||||
|
||||
<p>
|
||||
The languages that support shared_ptr also have support for using shared_ptr with directors.
|
||||
</p>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -122,9 +122,12 @@ swig -cffi -help
|
|||
<H3><a name="Lisp_nn5">27.2.2 Generating CFFI bindings</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
|
||||
As we mentioned earlier the ideal way to use SWIG is to use interface
|
||||
files. To illustrate the use of it, let's assume that we have a
|
||||
file named <i>test.h</i> with the following C code:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
#define y 5
|
||||
|
|
@ -155,7 +158,10 @@ void lispsort_double (int n, double * array);
|
|||
enum color { RED, BLUE, GREEN};
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
Corresponding to this we will write a simple interface file:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
%module test
|
||||
|
||||
|
|
@ -163,7 +169,9 @@ Corresponding to this we will write a simple interface file:
|
|||
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
The generated SWIG Code will be:
|
||||
</p>
|
||||
|
||||
<div class="targetlang"><pre>
|
||||
;;;SWIG wrapper code starts here
|
||||
|
|
@ -430,8 +438,10 @@ Also, while parsing the C++ file and generating C wrapper code SWIG
|
|||
%include "target/header.h"
|
||||
|
||||
</pre></div>
|
||||
<p>
|
||||
Various features which were available for C headers can also be used
|
||||
here. The target header which we are going to use here is:
|
||||
</p>
|
||||
<div class="code"><pre>
|
||||
namespace OpenDemo {
|
||||
class Test
|
||||
|
|
@ -478,8 +488,10 @@ namespace OpenDemo {
|
|||
%include "test.cpp"
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
SWIG generates 3 files, the first one is a C wrap which we don't show,
|
||||
the second is the plain CFFI wrapper which is as shown below:
|
||||
</p>
|
||||
<div class="targetlang"><pre>
|
||||
(cffi:defcfun ("_wrap_Test_x_set" Test_x_set) :void
|
||||
(self :pointer)
|
||||
|
|
@ -528,11 +540,13 @@ SWIG generates 3 files, the first one is a C wrap which we don't show,
|
|||
(cffi:defcfun ("_wrap_RandomUnitVectorOnXZPlane" RandomUnitVectorOnXZPlane) :pointer)
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
The output is pretty good but it fails in disambiguating overloaded
|
||||
functions such as the constructor, in this case. One way of
|
||||
resolving this problem is to make the interface use the rename
|
||||
directiv, but hopefully there are better solutions.
|
||||
In addition SWIG also generates, a CLOS file
|
||||
</p>
|
||||
|
||||
|
||||
<div class="targetlang"><pre>
|
||||
|
|
|
|||
|
|
@ -1008,11 +1008,10 @@ The following operators cannot be overloaded (mainly because they are not suppor
|
|||
<p>
|
||||
SWIG also accepts the <tt>__str__()</tt> member function which converts an object to a string. This function should return a const char*, preferably to static memory. This will be used for the <tt>print()</tt> and <tt>tostring()</tt> functions in Lua. Assuming the complex class has a function
|
||||
</p>
|
||||
<div class="code"><pre>const char* __str__()
|
||||
{
|
||||
static char buffer[255];
|
||||
sprintf(buffer, "Complex(%g, %g)", this->re(), this->im());
|
||||
return buffer;
|
||||
<div class="code"><pre>const char* __str__() {
|
||||
static char buffer[255];
|
||||
sprintf(buffer, "Complex(%g, %g)", this->re(), this->im());
|
||||
return buffer;
|
||||
}
|
||||
</pre></div>
|
||||
<p>
|
||||
|
|
@ -1031,11 +1030,10 @@ Complex(10, 12)
|
|||
<p>
|
||||
It is also possible to overload the operator<tt>[]</tt>, but currently this cannot be automatically performed. To overload the operator<tt>[]</tt> you need to provide two functions, <tt>__getitem__()</tt> and <tt>__setitem__()</tt>
|
||||
</p>
|
||||
<div class="code"><pre>class Complex
|
||||
{
|
||||
//....
|
||||
double __getitem__(int i)const; // i is the index, returns the data
|
||||
void __setitem__(int i, double d); // i is the index, d is the data
|
||||
<div class="code"><pre>class Complex {
|
||||
//....
|
||||
double __getitem__(int i)const; // i is the index, returns the data
|
||||
void __setitem__(int i, double d); // i is the index, d is the data
|
||||
};
|
||||
</pre></div>
|
||||
<p>
|
||||
|
|
|
|||
|
|
@ -949,7 +949,7 @@ Foo *BarToFoo(Bar *b) {
|
|||
}
|
||||
|
||||
Foo *IncrFoo(Foo *f, int i) {
|
||||
return f+i;
|
||||
return f+i;
|
||||
}
|
||||
%}
|
||||
</pre>
|
||||
|
|
@ -1057,7 +1057,7 @@ produces a single accessor function like this:
|
|||
<div class="code">
|
||||
<pre>
|
||||
int *Foo_x_get(Foo *self) {
|
||||
return self->x;
|
||||
return self->x;
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1092,11 +1092,11 @@ generates accessor functions such as this:
|
|||
<div class="code">
|
||||
<pre>
|
||||
Foo *Bar_f_get(Bar *b) {
|
||||
return &b->f;
|
||||
return &b->f;
|
||||
}
|
||||
|
||||
void Bar_f_set(Bar *b, Foo *val) {
|
||||
b->f = *val;
|
||||
b->f = *val;
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1633,9 +1633,8 @@ class DoubleArray {
|
|||
void setitem(int i, double val) {
|
||||
if ((i >= 0) && (i < n))
|
||||
ptr[i] = val;
|
||||
else {
|
||||
else
|
||||
throw RangeError();
|
||||
}
|
||||
}
|
||||
};
|
||||
</pre></div>
|
||||
|
|
@ -1888,9 +1887,9 @@ like this:
|
|||
<div class="targetlang">
|
||||
<pre>
|
||||
%typemap(out) int {
|
||||
$result = sv_newmortal();
|
||||
set_setiv($result, (IV) $1);
|
||||
argvi++;
|
||||
$result = sv_newmortal();
|
||||
set_setiv($result, (IV) $1);
|
||||
argvi++;
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2313,8 +2312,8 @@ Consider the following data structure:
|
|||
<div class="code"><pre>
|
||||
#define SIZE 8
|
||||
typedef struct {
|
||||
int values[SIZE];
|
||||
...
|
||||
int values[SIZE];
|
||||
...
|
||||
} Foo;
|
||||
|
||||
</pre></div>
|
||||
|
|
@ -2328,10 +2327,10 @@ To make the member writable, a "memberin" typemap can be used.
|
|||
|
||||
<div class="code"><pre>
|
||||
%typemap(memberin) int [SIZE] {
|
||||
int i;
|
||||
for (i = 0; i < SIZE; i++) {
|
||||
$1[i] = $input[i];
|
||||
}
|
||||
int i;
|
||||
for (i = 0; i < SIZE; i++) {
|
||||
$1[i] = $input[i];
|
||||
}
|
||||
}
|
||||
|
||||
</pre></div>
|
||||
|
|
@ -2600,48 +2599,48 @@ package example::Vector;
|
|||
%BLESSEDMEMBERS = ();
|
||||
|
||||
sub new () {
|
||||
my $self = shift;
|
||||
my @args = @_;
|
||||
$self = vectorc::new_Vector(@args);
|
||||
return undef if (!defined($self));
|
||||
bless $self, "example::Vector";
|
||||
$OWNER{$self} = 1;
|
||||
my %retval;
|
||||
tie %retval, "example::Vector", $self;
|
||||
return bless \%retval, "Vector";
|
||||
my $self = shift;
|
||||
my @args = @_;
|
||||
$self = vectorc::new_Vector(@args);
|
||||
return undef if (!defined($self));
|
||||
bless $self, "example::Vector";
|
||||
$OWNER{$self} = 1;
|
||||
my %retval;
|
||||
tie %retval, "example::Vector", $self;
|
||||
return bless \%retval, "Vector";
|
||||
}
|
||||
|
||||
sub DESTROY {
|
||||
return unless $_[0]->isa('HASH');
|
||||
my $self = tied(%{$_[0]});
|
||||
delete $ITERATORS{$self};
|
||||
if (exists $OWNER{$self}) {
|
||||
examplec::delete_Vector($self));
|
||||
delete $OWNER{$self};
|
||||
}
|
||||
return unless $_[0]->isa('HASH');
|
||||
my $self = tied(%{$_[0]});
|
||||
delete $ITERATORS{$self};
|
||||
if (exists $OWNER{$self}) {
|
||||
examplec::delete_Vector($self));
|
||||
delete $OWNER{$self};
|
||||
}
|
||||
}
|
||||
|
||||
sub FETCH {
|
||||
my ($self, $field) = @_;
|
||||
my $member_func = "vectorc::Vector_${field}_get";
|
||||
my $val = &$member_func($self);
|
||||
if (exists $BLESSEDMEMBERS{$field}) {
|
||||
return undef if (!defined($val));
|
||||
my %retval;
|
||||
tie %retval, $BLESSEDMEMBERS{$field}, $val;
|
||||
return bless \%retval, $BLESSEDMEMBERS{$field};
|
||||
}
|
||||
return $val;
|
||||
my ($self, $field) = @_;
|
||||
my $member_func = "vectorc::Vector_${field}_get";
|
||||
my $val = &$member_func($self);
|
||||
if (exists $BLESSEDMEMBERS{$field}) {
|
||||
return undef if (!defined($val));
|
||||
my %retval;
|
||||
tie %retval, $BLESSEDMEMBERS{$field}, $val;
|
||||
return bless \%retval, $BLESSEDMEMBERS{$field};
|
||||
}
|
||||
return $val;
|
||||
}
|
||||
|
||||
sub STORE {
|
||||
my ($self, $field, $newval) = @_;
|
||||
my $member_func = "vectorc::Vector_${field}_set";
|
||||
if (exists $BLESSEDMEMBERS{$field}) {
|
||||
&$member_func($self, tied(%{$newval}));
|
||||
} else {
|
||||
&$member_func($self, $newval);
|
||||
}
|
||||
my ($self, $field, $newval) = @_;
|
||||
my $member_func = "vectorc::Vector_${field}_set";
|
||||
if (exists $BLESSEDMEMBERS{$field}) {
|
||||
&$member_func($self, tied(%{$newval}));
|
||||
} else {
|
||||
&$member_func($self, $newval);
|
||||
}
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -2842,11 +2841,11 @@ this:
|
|||
|
||||
<div class="targetlang"><pre>
|
||||
sub dot_product {
|
||||
my @args = @_;
|
||||
$args[0] = tied(%{$args[0]}); # Get the real pointer values
|
||||
$args[1] = tied(%{$args[1]});
|
||||
my $result = vectorc::dot_product(@args);
|
||||
return $result;
|
||||
my @args = @_;
|
||||
$args[0] = tied(%{$args[0]}); # Get the real pointer values
|
||||
$args[1] = tied(%{$args[1]});
|
||||
my $result = vectorc::dot_product(@args);
|
||||
return $result;
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -2985,7 +2984,7 @@ sub set_transform
|
|||
for (my $j = 0; $j < 4, $j++)
|
||||
{
|
||||
mat44_set($a, $i, $j, $x->[i][j])
|
||||
}
|
||||
}
|
||||
}
|
||||
example.set_transform($im, $a);
|
||||
free_mat44($a);
|
||||
|
|
@ -3104,14 +3103,14 @@ the methods one() and two() (but not three()):
|
|||
%feature("director") Foo;
|
||||
class Foo {
|
||||
public:
|
||||
Foo(int foo);
|
||||
virtual void one();
|
||||
virtual void two();
|
||||
Foo(int foo);
|
||||
virtual void one();
|
||||
virtual void two();
|
||||
};
|
||||
|
||||
class Bar: public Foo {
|
||||
public:
|
||||
virtual void three();
|
||||
virtual void three();
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3279,9 +3278,9 @@ suffice in most cases:
|
|||
<div class="code">
|
||||
<pre>
|
||||
%feature("director:except") {
|
||||
if ($error != NULL) {
|
||||
throw Swig::DirectorMethodException();
|
||||
}
|
||||
if ($error != NULL) {
|
||||
throw Swig::DirectorMethodException();
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3305,8 +3304,8 @@ suitable exception handler:
|
|||
<div class="code">
|
||||
<pre>
|
||||
%exception {
|
||||
try { $action }
|
||||
catch (Swig::DirectorException &e) { SWIG_fail; }
|
||||
try { $action }
|
||||
catch (Swig::DirectorException &e) { SWIG_fail; }
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ If the module is in PHP's default extension directory, you can omit the path.
|
|||
<p>
|
||||
For some SAPIs (for example, the CLI SAPI) you can instead use the
|
||||
<a href="http://php.net/manual/en/function.dl.php">dl() function</a> to load
|
||||
an extension at run time, by adding a like like this to the start of each
|
||||
an extension at run time, by adding a line like this to the start of each
|
||||
PHP script which uses your extension:
|
||||
</p>
|
||||
|
||||
|
|
@ -390,8 +390,7 @@ Although PHP does not support overloading functions natively, swig
|
|||
will generate dispatch functions which will use <tt>%typecheck</tt>
|
||||
typemaps to allow overloading. This dispatch function's operation and
|
||||
precedence is described in <a
|
||||
href="SWIGPlus.html#SWIGPlus_overloaded_methods">Wrapping
|
||||
Overloaded Functions and Methods</a>.
|
||||
href="SWIGPlus.html#SWIGPlus_overloaded_methods">Overloaded functions and methods</a>.
|
||||
</p>
|
||||
|
||||
<!-- This isn't correct for 1.3.30 and needs rewriting to reflect reality
|
||||
|
|
@ -820,6 +819,15 @@ Results in the following in "example.php"
|
|||
echo "example.php execution\n";
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
The <b>version</b> pragma can be used to add version to generated PHP extension module. The version is inserted in the zend_module_entry block.
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
%module example
|
||||
%pragma(php) version="1.5"
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
The <b>include</b> pragma is a short cut to add include statements to
|
||||
the example.php file.
|
||||
|
|
@ -977,14 +985,14 @@ the methods one() and two() (but not three()):
|
|||
%feature("director") Foo;
|
||||
class Foo {
|
||||
public:
|
||||
Foo(int foo);
|
||||
virtual void one();
|
||||
virtual void two();
|
||||
Foo(int foo);
|
||||
virtual void one();
|
||||
virtual void two();
|
||||
};
|
||||
|
||||
class Bar: public Foo {
|
||||
public:
|
||||
virtual void three();
|
||||
virtual void three();
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1116,12 +1124,12 @@ Here is an example:
|
|||
<pre>
|
||||
class Foo {
|
||||
public:
|
||||
...
|
||||
...
|
||||
};
|
||||
class FooContainer {
|
||||
public:
|
||||
void addFoo(Foo *);
|
||||
...
|
||||
void addFoo(Foo *);
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1166,9 +1174,9 @@ should suffice in most cases:
|
|||
<div class="code">
|
||||
<pre>
|
||||
%feature("director:except") {
|
||||
if ($error == FAILURE) {
|
||||
throw Swig::DirectorMethodException();
|
||||
}
|
||||
if ($error == FAILURE) {
|
||||
throw Swig::DirectorMethodException();
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1195,8 +1203,8 @@ suitable exception handler:
|
|||
<div class="code">
|
||||
<pre>
|
||||
%exception {
|
||||
try { $action }
|
||||
catch (Swig::DirectorException &e) { SWIG_fail; }
|
||||
try { $action }
|
||||
catch (Swig::DirectorException &e) { SWIG_fail; }
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -230,8 +230,8 @@ For example, given this C++ class declaration:
|
|||
class Shape
|
||||
{
|
||||
public:
|
||||
static void print();
|
||||
static int nshapes;
|
||||
static void print();
|
||||
static int nshapes;
|
||||
};
|
||||
</pre></div>
|
||||
|
||||
|
|
|
|||
|
|
@ -226,16 +226,15 @@ resulting C file should be built as a python extension, inserting the module
|
|||
#include "example.h"
|
||||
|
||||
int fact(int n) {
|
||||
if (n < 0){ /* This should probably return an error, but this is simpler */
|
||||
return 0;
|
||||
}
|
||||
if (n == 0) {
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
/* testing for overflow would be a good idea here */
|
||||
return n * fact(n-1);
|
||||
}
|
||||
if (n < 0) { /* This should probably return an error, but this is simpler */
|
||||
return 0;
|
||||
}
|
||||
if (n == 0) {
|
||||
return 1;
|
||||
} else {
|
||||
/* testing for overflow would be a good idea here */
|
||||
return n * fact(n-1);
|
||||
}
|
||||
}
|
||||
|
||||
</pre>
|
||||
|
|
@ -1276,7 +1275,7 @@ Foo *BarToFoo(Bar *b) {
|
|||
}
|
||||
|
||||
Foo *IncrFoo(Foo *f, int i) {
|
||||
return f+i;
|
||||
return f+i;
|
||||
}
|
||||
%}
|
||||
</pre>
|
||||
|
|
@ -1386,7 +1385,7 @@ example, consider this:
|
|||
<div class="code">
|
||||
<pre>
|
||||
struct Bar {
|
||||
int x[16];
|
||||
int x[16];
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1716,9 +1715,9 @@ Similarly, if you have a class like this,
|
|||
<pre>
|
||||
class Foo {
|
||||
public:
|
||||
Foo();
|
||||
Foo(const Foo &);
|
||||
...
|
||||
Foo();
|
||||
Foo(const Foo &);
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1894,6 +1893,14 @@ Also, be aware that certain operators don't map cleanly to Python. For instance
|
|||
overloaded assignment operators don't map to Python semantics and will be ignored.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Operator overloading is implemented in the <tt>pyopers.swg</tt> library file.
|
||||
In particular overloaded operators are marked with the <tt>python:maybecall</tt> feature, also known as <tt>%pythonmaybecall</tt>.
|
||||
This feature forces SWIG to generate code that return an instance of Python's <tt>NotImplemented</tt>
|
||||
instead of raising an exception when the comparison fails, that is, on any kind of error.
|
||||
This follows the guidelines in <a href="https://www.python.org/dev/peps/pep-0207/">PEP 207 - Rich Comparisons</a> and <a href="https://docs.python.org/3/library/constants.html#NotImplemented">NotImplemented Python constant</a>.
|
||||
</p>
|
||||
|
||||
<H3><a name="Python_nn25">36.3.12 C++ namespaces</a></H3>
|
||||
|
||||
|
||||
|
|
@ -1943,11 +1950,11 @@ For example:
|
|||
%rename(Bar_spam) Bar::spam;
|
||||
|
||||
namespace Foo {
|
||||
int spam();
|
||||
int spam();
|
||||
}
|
||||
|
||||
namespace Bar {
|
||||
int spam();
|
||||
int spam();
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2158,9 +2165,9 @@ have a class like this
|
|||
<pre>
|
||||
class Foo {
|
||||
public:
|
||||
int x;
|
||||
int spam(int);
|
||||
...
|
||||
int x;
|
||||
int spam(int);
|
||||
...
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -2171,19 +2178,19 @@ then SWIG transforms it into a set of low-level procedural wrappers. For example
|
|||
<div class="code">
|
||||
<pre>
|
||||
Foo *new_Foo() {
|
||||
return new Foo();
|
||||
return new Foo();
|
||||
}
|
||||
void delete_Foo(Foo *f) {
|
||||
delete f;
|
||||
delete f;
|
||||
}
|
||||
int Foo_x_get(Foo *f) {
|
||||
return f->x;
|
||||
return f->x;
|
||||
}
|
||||
void Foo_x_set(Foo *f, int value) {
|
||||
f->x = value;
|
||||
f->x = value;
|
||||
}
|
||||
int Foo_spam(Foo *f, int arg1) {
|
||||
return f->spam(arg1);
|
||||
return f->spam(arg1);
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2302,10 +2309,10 @@ please refer to the python documentation:</p>
|
|||
<div class="code">
|
||||
<pre>
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
PyObject *dict;
|
||||
PyObject *args;
|
||||
PyObject *message;
|
||||
PyObject_HEAD
|
||||
PyObject *dict;
|
||||
PyObject *args;
|
||||
PyObject *message;
|
||||
} PyBaseExceptionObject;
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2315,12 +2322,12 @@ typedef struct {
|
|||
<div class="code">
|
||||
<pre>
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
void *ptr;
|
||||
swig_type_info *ty;
|
||||
int own;
|
||||
PyObject *next;
|
||||
PyObject *dict;
|
||||
PyObject_HEAD
|
||||
void *ptr;
|
||||
swig_type_info *ty;
|
||||
int own;
|
||||
PyObject *next;
|
||||
PyObject *dict;
|
||||
} SwigPyObject;
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2331,13 +2338,13 @@ typedef struct {
|
|||
<pre>
|
||||
class MyException {
|
||||
public:
|
||||
MyException (const char *msg_);
|
||||
~MyException ();
|
||||
MyException (const char *msg_);
|
||||
~MyException ();
|
||||
|
||||
const char *what () const;
|
||||
const char *what () const;
|
||||
|
||||
private:
|
||||
char *msg;
|
||||
char *msg;
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2364,9 +2371,9 @@ strings, you can define an <tt>'operator+ (const char*)'</tt> method :</p>
|
|||
<pre>
|
||||
class MyString {
|
||||
public:
|
||||
MyString (const char *init);
|
||||
MyString operator+ (const char *other) const;
|
||||
...
|
||||
MyString (const char *init);
|
||||
MyString operator+ (const char *other) const;
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2465,11 +2472,12 @@ slot entries. For example, suppose you have this class:
|
|||
<pre>
|
||||
class Twit {
|
||||
public:
|
||||
Twit operator+ (const Twit& twit) const;
|
||||
Twit operator+ (const Twit& twit) const;
|
||||
|
||||
// Forward to operator+
|
||||
Twit add (const Twit& twit) const
|
||||
{ return *this + twit; }
|
||||
// Forward to operator+
|
||||
Twit add (const Twit& twit) const {
|
||||
return *this + twit;
|
||||
}
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2557,9 +2565,9 @@ the function callback in the tp_hash slot for the builtin type for <tt>MyClass</
|
|||
<div class="code">
|
||||
<pre>
|
||||
static PyHeapTypeObject SwigPyBuiltin__MyClass_type = {
|
||||
...
|
||||
(hashfunc) myHashFunc, /* tp_hash */
|
||||
...
|
||||
...
|
||||
(hashfunc) myHashFunc, /* tp_hash */
|
||||
...
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -2628,8 +2636,8 @@ ownership of the result. For example:
|
|||
<pre>
|
||||
class Foo {
|
||||
public:
|
||||
Foo();
|
||||
Foo bar();
|
||||
Foo();
|
||||
Foo bar();
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2658,9 +2666,9 @@ they came from. Therefore, the ownership is set to zero. For example:
|
|||
<pre>
|
||||
class Foo {
|
||||
public:
|
||||
...
|
||||
Foo *spam();
|
||||
...
|
||||
...
|
||||
Foo *spam();
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2699,8 +2707,8 @@ or global variable. For example, consider this interface:
|
|||
%module example
|
||||
|
||||
struct Foo {
|
||||
int value;
|
||||
Foo *next;
|
||||
int value;
|
||||
Foo *next;
|
||||
};
|
||||
|
||||
Foo *head = 0;
|
||||
|
|
@ -2931,15 +2939,15 @@ the methods one() and two() (but not three()):
|
|||
%feature("director") Foo;
|
||||
class Foo {
|
||||
public:
|
||||
Foo(int foo);
|
||||
virtual ~Foo();
|
||||
virtual void one();
|
||||
virtual void two();
|
||||
Foo(int foo);
|
||||
virtual ~Foo();
|
||||
virtual void one();
|
||||
virtual void two();
|
||||
};
|
||||
|
||||
class Bar: public Foo {
|
||||
public:
|
||||
virtual void three();
|
||||
virtual void three();
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3079,12 +3087,12 @@ references. Here is an example:
|
|||
<pre>
|
||||
class Foo {
|
||||
public:
|
||||
...
|
||||
...
|
||||
};
|
||||
class FooContainer {
|
||||
public:
|
||||
void addFoo(Foo *);
|
||||
...
|
||||
void addFoo(Foo *);
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3125,9 +3133,9 @@ suffice in most cases:
|
|||
<div class="code">
|
||||
<pre>
|
||||
%feature("director:except") {
|
||||
if ($error != NULL) {
|
||||
throw Swig::DirectorMethodException();
|
||||
}
|
||||
if ($error != NULL) {
|
||||
throw Swig::DirectorMethodException();
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3154,8 +3162,8 @@ suitable exception handler:
|
|||
<div class="code">
|
||||
<pre>
|
||||
%exception {
|
||||
try { $action }
|
||||
catch (Swig::DirectorException &e) { SWIG_fail; }
|
||||
try { $action }
|
||||
catch (Swig::DirectorException &e) { SWIG_fail; }
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3232,7 +3240,7 @@ references, such as
|
|||
<pre>
|
||||
class Foo {
|
||||
…
|
||||
virtual const int& bar();
|
||||
virtual const int& bar();
|
||||
…
|
||||
};
|
||||
</pre>
|
||||
|
|
@ -3250,7 +3258,7 @@ types, wherever possible, for example
|
|||
<pre>
|
||||
class Foo {
|
||||
…
|
||||
virtual int bar();
|
||||
virtual int bar();
|
||||
…
|
||||
};
|
||||
</pre>
|
||||
|
|
@ -3503,7 +3511,7 @@ def bar(*args):
|
|||
|
||||
class Foo {
|
||||
public:
|
||||
int bar(int x);
|
||||
int bar(int x);
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3540,7 +3548,7 @@ proxy, just before the return statement.
|
|||
|
||||
class Foo {
|
||||
public:
|
||||
int bar(int x);
|
||||
int bar(int x);
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3569,7 +3577,7 @@ SWIG version 1.3.28 you can use the directive forms
|
|||
|
||||
class Foo {
|
||||
public:
|
||||
int bar(int x);
|
||||
int bar(int x);
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3598,8 +3606,8 @@ as it will then get attached to all the overloaded C++ methods. For example:
|
|||
|
||||
class Foo {
|
||||
public:
|
||||
int bar(int x);
|
||||
int bar();
|
||||
int bar(int x);
|
||||
int bar();
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -4134,11 +4142,11 @@ Sometimes a C function expects an array to be passed as a pointer. For example,
|
|||
<div class="code">
|
||||
<pre>
|
||||
int sumitems(int *first, int nitems) {
|
||||
int i, sum = 0;
|
||||
for (i = 0; i < nitems; i++) {
|
||||
sum += first[i];
|
||||
}
|
||||
return sum;
|
||||
int i, sum = 0;
|
||||
for (i = 0; i < nitems; i++) {
|
||||
sum += first[i];
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -6038,7 +6046,7 @@ zipimporter requires python-3.5.1 or newer to work with subpackages.
|
|||
|
||||
<p>
|
||||
When SWIG creates wrappers from an interface file, say foo.i, two Python modules are
|
||||
created. There is a pure Python module module (foo.py) and C/C++ code which is
|
||||
created. There is a pure Python module (foo.py) and C/C++ code which is
|
||||
built and linked into a dynamically (or statically) loaded low-level module _foo
|
||||
(see the <a href="Python.html#Python_nn3">Preliminaries section</a> for details). So, the interface
|
||||
file really defines two Python modules. How these two modules are loaded is
|
||||
|
|
@ -6513,12 +6521,14 @@ string that cannot be completely decoded as UTF-8:
|
|||
<div class="code"><pre>
|
||||
%module example
|
||||
|
||||
%include <std_string.i>
|
||||
|
||||
%inline %{
|
||||
|
||||
const char* non_utf8_c_str(void) {
|
||||
return "h\xe9llo w\xc3\xb6rld";
|
||||
const char * non_utf8_c_str(void) {
|
||||
return "h\xe9llo w\xc3\xb6rld";
|
||||
}
|
||||
|
||||
void instring(const char *s) {
|
||||
...
|
||||
}
|
||||
|
||||
%}
|
||||
|
|
@ -6582,6 +6592,20 @@ For more details about the <tt>surrogateescape</tt> error handler, please see
|
|||
<a href="https://www.python.org/dev/peps/pep-0383/">PEP 383</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
When Python 3 strings are passed to the C/C++ layer, they are expected to be valid UTF8 Unicode strings too.
|
||||
For example, when the <tt>instring</tt> method above is wrapped and called, any invalid UTF8 Unicode code strings
|
||||
will result in a TypeError because the attempted conversion fails:
|
||||
</p>
|
||||
|
||||
<div class="targetlang"><pre>
|
||||
>>> 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>
|
||||
In some cases, users may wish to instead handle all byte strings as bytes
|
||||
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
|
||||
versions do not, but return a status value to indicate success (<tt>SWIG_OK</tt>). While more akward to use, this allows you to write typemaps that report more helpful error messages, like:</p>
|
||||
versions do not, but return a status value to indicate success (<tt>SWIG_OK</tt>). While more awkward to use, this allows you to write typemaps that report more helpful error messages, like:</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
|
|
@ -3704,7 +3704,7 @@ value: </p>
|
|||
<pre>%typemap(in) (int nattributes, const char **names, const int *values)
|
||||
(VALUE keys_arr, int i, VALUE key, VALUE val) {
|
||||
Check_Type($input, T_HASH);
|
||||
<b>$1 = NUM2INT(rb_funcall($input, rb_intern("size"), 0, NULL));</b>
|
||||
<b>$1 = NUM2INT(rb_funcall($input, rb_intern("size"), 0, Qnil));</b>
|
||||
}</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -3717,7 +3717,7 @@ the keys and values from the hash: </p>
|
|||
<pre>%typemap(in) (int nattributes, const char **names, const int *values)
|
||||
(VALUE keys_arr, int i, VALUE key, VALUE val) {
|
||||
Check_Type($input, T_HASH);
|
||||
$1 = NUM2INT(rb_funcall($input, rb_intern("size"), 0, NULL));
|
||||
$1 = NUM2INT(rb_funcall($input, rb_intern("size"), 0, Qnil));
|
||||
<b>$2 = NULL;
|
||||
$3 = NULL;
|
||||
if ($1 > 0) {
|
||||
|
|
@ -3736,13 +3736,13 @@ of the keys) and then start looping over the elements in that array: </p>
|
|||
<pre>%typemap(in) (int nattributes, const char **names, const int *values)
|
||||
(VALUE keys_arr, int i, VALUE key, VALUE val) {
|
||||
Check_Type($input, T_HASH);
|
||||
$1 = NUM2INT(rb_funcall($input, rb_intern("size"), 0, NULL));
|
||||
$1 = NUM2INT(rb_funcall($input, rb_intern("size"), 0, Qnil));
|
||||
$2 = NULL;
|
||||
$3 = NULL;
|
||||
if ($1 > 0) {
|
||||
$2 = (char **) malloc($1*sizeof(char *));
|
||||
$3 = (int *) malloc($1*sizeof(int));
|
||||
<b>keys_arr = rb_funcall($input, rb_intern("keys"), 0, NULL);
|
||||
<b>keys_arr = rb_funcall($input, rb_intern("keys"), 0, Qnil);
|
||||
for (i = 0; i < $1; i++) {
|
||||
}</b>
|
||||
}
|
||||
|
|
@ -3758,13 +3758,13 @@ corresponding to that key in the hash: </p>
|
|||
<pre>%typemap(in) (int nattributes, const char **names, const int *values)
|
||||
(VALUE keys_arr, int i, VALUE key, VALUE val) {
|
||||
Check_Type($input, T_HASH);
|
||||
$1 = NUM2INT(rb_funcall($input, rb_intern("size"), 0, NULL));
|
||||
$1 = NUM2INT(rb_funcall($input, rb_intern("size"), 0, Qnil));
|
||||
$2 = NULL;
|
||||
$3 = NULL;
|
||||
if ($1 > 0) {
|
||||
$2 = (char **) malloc($1*sizeof(char *));
|
||||
$3 = (int *) malloc($1*sizeof(int));
|
||||
keys_arr = rb_funcall($input, rb_intern("keys"), 0, NULL);
|
||||
keys_arr = rb_funcall($input, rb_intern("keys"), 0, Qnil);
|
||||
for (i = 0; i < $1; i++) {
|
||||
<b>key = rb_ary_entry(keys_arr, i);
|
||||
val = rb_hash_aref($input, key);</b>
|
||||
|
|
@ -3781,13 +3781,13 @@ value is a <tt>Fixnum</tt>: </p>
|
|||
<pre>%typemap(in) (int nattributes, const char **names, const int *values)
|
||||
(VALUE keys_arr, int i, VALUE key, VALUE val) {
|
||||
Check_Type($input, T_HASH);
|
||||
$1 = NUM2INT(rb_funcall($input, rb_intern("size"), 0, NULL));
|
||||
$1 = NUM2INT(rb_funcall($input, rb_intern("size"), 0, Qnil));
|
||||
$2 = NULL;
|
||||
$3 = NULL;
|
||||
if ($1 > 0) {
|
||||
$2 = (char **) malloc($1*sizeof(char *));
|
||||
$3 = (int *) malloc($1*sizeof(int));
|
||||
keys_arr = rb_funcall($input, rb_intern("keys"), 0, NULL);
|
||||
keys_arr = rb_funcall($input, rb_intern("keys"), 0, Qnil);
|
||||
for (i = 0; i < $1; i++) {
|
||||
key = rb_ary_entry(keys_arr, i);
|
||||
val = rb_hash_aref($input, key);
|
||||
|
|
@ -3805,13 +3805,13 @@ equivalents and store them in our local C arrays: </p>
|
|||
<pre>%typemap(in) (int nattributes, const char **names, const int *values)
|
||||
(VALUE keys_arr, int i, VALUE key, VALUE val) {
|
||||
Check_Type($input, T_HASH);
|
||||
$1 = NUM2INT(rb_funcall($input, rb_intern("size"), 0, NULL));
|
||||
$1 = NUM2INT(rb_funcall($input, rb_intern("size"), 0, Qnil));
|
||||
$2 = NULL;
|
||||
$3 = NULL;
|
||||
if ($1 > 0) {
|
||||
$2 = (char **) malloc($1*sizeof(char *));
|
||||
$3 = (int *) malloc($1*sizeof(int));
|
||||
keys_arr = rb_funcall($input, rb_intern("keys"), 0, NULL);
|
||||
keys_arr = rb_funcall($input, rb_intern("keys"), 0, Qnil);
|
||||
for (i = 0; i < $1; i++) {
|
||||
key = rb_ary_entry(keys_arr, i);
|
||||
val = rb_hash_aref($input, key);
|
||||
|
|
|
|||
|
|
@ -163,6 +163,32 @@ can be obtained by typing <tt>swig -help</tt> or <tt>swig
|
|||
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
Arguments may also be passed in a command-line options file (also known as a
|
||||
response file) which is useful if they exceed the system command line length
|
||||
limit. To do this, put the arguments in a file, then provide the file name
|
||||
prefixed with <tt>@</tt> like so:
|
||||
</p>
|
||||
|
||||
<div class="shell"><pre>
|
||||
swig @<em>file</em>
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
The options read from the file are inserted in place of the file option. If the
|
||||
file does not exist, or cannot be read, then the option will be treated
|
||||
literally and not removed.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Options in the file are separated by whitespace. A whitespace character may be
|
||||
included in an option by surrounding the entire option in either single or
|
||||
double quotes. Any character (including a backslash) may be included by
|
||||
prefixing the character to be included with a backslash. The file may itself
|
||||
contain additional <tt>@file</tt> options; any such options will be processed
|
||||
recursively.
|
||||
</p>
|
||||
|
||||
<H3><a name="SWIG_nn3">5.1.1 Input format</a></H3>
|
||||
|
||||
|
||||
|
|
@ -389,7 +415,7 @@ For example
|
|||
/* bar not wrapped unless foo has been defined and
|
||||
the declaration of bar within foo has already been parsed */
|
||||
int foo::bar(int) {
|
||||
... whatever ...
|
||||
... whatever ...
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1043,14 +1069,14 @@ expect :</p>
|
|||
<div class="targetlang"><pre>
|
||||
# Copy a file
|
||||
def filecopy(source, target):
|
||||
f1 = fopen(source, "r")
|
||||
f2 = fopen(target, "w")
|
||||
buffer = malloc(8192)
|
||||
nbytes = fread(buffer, 8192, 1, f1)
|
||||
while (nbytes > 0):
|
||||
fwrite(buffer, 8192, 1, f2)
|
||||
nbytes = fread(buffer, 8192, 1, f1)
|
||||
free(buffer)
|
||||
f1 = fopen(source, "r")
|
||||
f2 = fopen(target, "w")
|
||||
buffer = malloc(8192)
|
||||
nbytes = fread(buffer, 8192, 1, f1)
|
||||
while (nbytes > 0):
|
||||
fwrite(buffer, 8192, 1, f2)
|
||||
nbytes = fread(buffer, 8192, 1, f1)
|
||||
free(buffer)
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
|
|
@ -1236,9 +1262,9 @@ creating a wrapper equivalent to the following:
|
|||
|
||||
<div class="code"><pre>
|
||||
double wrap_dot_product(Vector *a, Vector *b) {
|
||||
Vector x = *a;
|
||||
Vector y = *b;
|
||||
return dot_product(x, y);
|
||||
Vector x = *a;
|
||||
Vector y = *b;
|
||||
return dot_product(x, y);
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -1266,12 +1292,12 @@ pointers. As a result, SWIG creates a wrapper like this:
|
|||
|
||||
<div class="code"><pre>
|
||||
Vector *wrap_cross_product(Vector *v1, Vector *v2) {
|
||||
Vector x = *v1;
|
||||
Vector y = *v2;
|
||||
Vector *result;
|
||||
result = (Vector *) malloc(sizeof(Vector));
|
||||
*(result) = cross(x, y);
|
||||
return result;
|
||||
Vector x = *v1;
|
||||
Vector y = *v2;
|
||||
Vector *result;
|
||||
result = (Vector *) malloc(sizeof(Vector));
|
||||
*(result) = cross(x, y);
|
||||
return result;
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -1280,10 +1306,10 @@ or if SWIG was run with the <tt>-c++</tt> option:</p>
|
|||
|
||||
<div class="code"><pre>
|
||||
Vector *wrap_cross(Vector *v1, Vector *v2) {
|
||||
Vector x = *v1;
|
||||
Vector y = *v2;
|
||||
Vector *result = new Vector(cross(x, y)); // Uses default copy constructor
|
||||
return result;
|
||||
Vector x = *v1;
|
||||
Vector y = *v2;
|
||||
Vector *result = new Vector(cross(x, y)); // Uses default copy constructor
|
||||
return result;
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -1736,6 +1762,16 @@ already defined in the target scripting language. However, if you are
|
|||
careful about namespaces and your use of modules, you can usually
|
||||
avoid these problems.</p>
|
||||
|
||||
<p>
|
||||
When wrapping C code, simple use of identifiers/symbols with <tt>%rename</tt> usually suffices.
|
||||
When wrapping C++ code, simple use of simple identifiers/symbols with <tt>%rename</tt> might be too
|
||||
limiting when using C++ features such as function overloading, default arguments, namespaces, template specialization etc.
|
||||
If you are using the <tt>%rename</tt> directive and C++, make sure you read the
|
||||
<a href="SWIGPlus.html">SWIG and C++</a> chapter and in particular the section on
|
||||
<a href="SWIGPlus.html#SWIGPlus_ambiguity_resolution_renaming">Renaming and ambiguity resolution</a>
|
||||
for method overloading and default arguments.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Closely related to <tt>%rename</tt> is the <tt>%ignore</tt> directive. <tt>%ignore</tt> instructs SWIG
|
||||
to ignore declarations that match a given identifier. For example:
|
||||
|
|
@ -2078,7 +2114,7 @@ except those consisting of capital letters only:
|
|||
<p>
|
||||
Finally, variants of <tt>%rename</tt> and <tt>%ignore</tt> directives can be used to help
|
||||
wrap C++ overloaded functions and methods or C++ methods which use default arguments. This is described in the
|
||||
<a href="SWIGPlus.html#SWIGPlus_ambiguity_resolution_renaming">Ambiguity resolution and renaming</a> section in the C++ chapter.
|
||||
<a href="SWIGPlus.html#SWIGPlus_ambiguity_resolution_renaming">Renaming and ambiguity resolution</a> section in the C++ chapter.
|
||||
</p>
|
||||
|
||||
|
||||
|
|
@ -2167,7 +2203,7 @@ in the C++ chapter for further details.
|
|||
<p>
|
||||
Occasionally, a C library may include functions that expect to receive
|
||||
pointers to functions--possibly to serve as callbacks. SWIG
|
||||
provides full support for function pointers provided that the callback
|
||||
provides full support for function pointers when the callback
|
||||
functions are defined in C and not in the target language. For example,
|
||||
consider a function like this:
|
||||
</p>
|
||||
|
|
@ -2311,7 +2347,9 @@ And now, a final note about function pointer support. Although SWIG
|
|||
does not normally allow callback functions to be written in the target language, this
|
||||
can be accomplished with the use of typemaps and other advanced SWIG features.
|
||||
See the <a href="Typemaps.html#Typemaps">Typemaps chapter</a> for more about typemaps
|
||||
and individual target language chapters for more on callbacks and the 'director' feature.
|
||||
and individual target language chapters for more on callbacks.
|
||||
The 'director' feature can be used to make callbacks from C/C++ into the target language,
|
||||
see <a href="SWIGPlus.html#SWIGPlus_target_language_callbacks">Callbacks to the target language</a>.
|
||||
</p>
|
||||
|
||||
<H2><a name="SWIG_nn31">5.5 Structures and unions</a></H2>
|
||||
|
|
@ -2368,10 +2406,10 @@ defined in the interface. For example:
|
|||
|
||||
<div class="code"><pre>
|
||||
struct Vector *new_Vector() {
|
||||
return (Vector *) calloc(1, sizeof(struct Vector));
|
||||
return (Vector *) calloc(1, sizeof(struct Vector));
|
||||
}
|
||||
void delete_Vector(struct Vector *obj) {
|
||||
free(obj);
|
||||
free(obj);
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2602,10 +2640,10 @@ like this:
|
|||
<div class="code">
|
||||
<pre>
|
||||
WORD Foo_w_get(Foo *f) {
|
||||
return f->w;
|
||||
return f->w;
|
||||
}
|
||||
void Foo_w_set(FOO *f, WORD value) {
|
||||
f->w = value;
|
||||
f->w = value;
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2896,7 +2934,7 @@ instead of a method. To do this, you might write some code like this:
|
|||
<pre>
|
||||
// Add a new attribute to Vector
|
||||
%extend Vector {
|
||||
const double magnitude;
|
||||
const double magnitude;
|
||||
}
|
||||
// Now supply the implementation of the Vector_magnitude_get function
|
||||
%{
|
||||
|
|
@ -3293,11 +3331,27 @@ Vector *new_Vector() {
|
|||
return (Vector *) malloc(sizeof(Vector));
|
||||
}
|
||||
%}
|
||||
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
The <tt>%inline</tt> directive inserts all of the code that follows
|
||||
This is the same as writing:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
%{
|
||||
/* Create a new vector */
|
||||
Vector *new_Vector() {
|
||||
return (Vector *) malloc(sizeof(Vector));
|
||||
}
|
||||
%}
|
||||
|
||||
/* Create a new vector */
|
||||
Vector *new_Vector() {
|
||||
return (Vector *) malloc(sizeof(Vector));
|
||||
}
|
||||
</pre></div>
|
||||
<p>
|
||||
In other words, the <tt>%inline</tt> directive inserts all of the code that follows
|
||||
verbatim into the header portion of an interface file. The code is
|
||||
then parsed by both the SWIG preprocessor and parser.
|
||||
Thus, the above example creates a new command <tt>new_Vector</tt> using only one
|
||||
|
|
@ -3305,6 +3359,11 @@ declaration. Since the code inside an <tt>%inline %{ ... %}</tt> block
|
|||
is given to both the C compiler and SWIG, it is illegal to include any
|
||||
SWIG directives inside a <tt>%{ ... %}</tt> block.</p>
|
||||
|
||||
|
||||
<p>
|
||||
<b>Note:</b> The usual SWIG C preprocessor rules apply to code in <tt>%apply</tt> blocks when SWIG parses this code. For example, as mentioned earlier, <a href="SWIG.html#SWIG_nn6">SWIG's C Preprocessor</a> does not follow <tt>#include</tt> directives by default.
|
||||
</p>
|
||||
|
||||
<H3><a name="SWIG_nn44">5.6.4 Initialization blocks</a></H3>
|
||||
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -121,15 +121,15 @@ In this example we bind from C a function and a global variable into Scilab. The
|
|||
double Foo = 3.0;
|
||||
|
||||
int fact(int n) {
|
||||
if (n < 0) {
|
||||
return 0;
|
||||
}
|
||||
else if (n == 0) {
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
return n * fact(n-1);
|
||||
}
|
||||
if (n < 0) {
|
||||
return 0;
|
||||
}
|
||||
else if (n == 0) {
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
return n * fact(n-1);
|
||||
}
|
||||
}
|
||||
%}
|
||||
</pre></div>
|
||||
|
|
@ -896,8 +896,8 @@ Let's see it on an example of a struct with two members:
|
|||
%inline %{
|
||||
|
||||
typedef struct {
|
||||
int x;
|
||||
int arr[4];
|
||||
int x;
|
||||
int arr[4];
|
||||
} Foo;
|
||||
|
||||
%}
|
||||
|
|
@ -1133,21 +1133,21 @@ But we can use either use the <tt>get_perimeter()</tt> function of the parent cl
|
|||
|
||||
|
||||
<p>
|
||||
As explained in <a href="SWIGPlus.html#SWIGPlus_overloaded_methods">6.15</a> SWIG provides support for overloaded functions and constructors.
|
||||
As explained in <a href="SWIGPlus.html#SWIGPlus_overloaded_methods">Overloaded functions and methods</a> SWIG provides support for overloaded functions and constructors.
|
||||
</p>
|
||||
|
||||
<p>As SWIG knows pointer types, the overloading works also with pointer types, here is is an example with a function <tt>magnify</tt> overloaded for the previous classes <tt>Shape</tt> and <tt>Circle</tt>:
|
||||
<p>As SWIG knows pointer types, the overloading works also with pointer types, here is an example with a function <tt>magnify</tt> overloaded for the previous classes <tt>Shape</tt> and <tt>Circle</tt>:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
%module example
|
||||
|
||||
void magnify(Square *square, double factor) {
|
||||
square->size *= factor;
|
||||
square->size *= factor;
|
||||
};
|
||||
|
||||
void magnify(Circle *circle, double factor) {
|
||||
square->radius *= factor;
|
||||
square->radius *= factor;
|
||||
};
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -1620,11 +1620,11 @@ void printArray(int values[], int len) {
|
|||
|
||||
|
||||
<p>
|
||||
There are no specific typemaps for pointer-to-pointers, they are are mapped as pointers in Scilab.
|
||||
There are no specific typemaps for pointer-to-pointers, they are mapped as pointers in Scilab.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Pointer-to-pointers are sometimes used to implement matrices in C. The following is a an example of this:
|
||||
Pointer-to-pointers are sometimes used to implement matrices in C. The following is an example of this:
|
||||
</p>
|
||||
|
||||
|
||||
|
|
@ -2062,7 +2062,7 @@ In this mode, the following SWIG options may be used to setup the build:
|
|||
Let's give an example how to build a module <tt>example</tt>, composed of two sources, and using a library dependency:
|
||||
</p>
|
||||
<ul>
|
||||
<li>the sources are <tt>baa1.c</tt> and <tt>baa2.c</tt> (and are stored in in the current directory)</li>
|
||||
<li>the sources are <tt>baa1.c</tt> and <tt>baa2.c</tt> (and are stored in the current directory)</li>
|
||||
<li>the library is <tt>libfoo</tt> in <tt>/opt/foo</tt> (headers stored in <tt>/opt/foo/include</tt>, and shared library in <tt>/opt/foo/lib</tt>)</li>
|
||||
</ul>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>SWIG-3.0 Documentation</title>
|
||||
<title>SWIG-4.0 Documentation</title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
</head>
|
||||
<body bgcolor="#ffffff">
|
||||
<H1><a name="Sections">SWIG-3.0 Documentation</a></H1>
|
||||
<H1><a name="Sections">SWIG-4.0 Documentation</a></H1>
|
||||
|
||||
<p>
|
||||
Last update : SWIG-3.0.13 (in progress)
|
||||
Last update : SWIG-4.0.0 (in progress)
|
||||
</p>
|
||||
|
||||
<H2><a name="Sections_Sections">Sections</a></H2>
|
||||
|
|
|
|||
|
|
@ -958,7 +958,7 @@ Foo *BarToFoo(Bar *b) {
|
|||
}
|
||||
|
||||
Foo *IncrFoo(Foo *f, int i) {
|
||||
return f+i;
|
||||
return f+i;
|
||||
}
|
||||
%}
|
||||
</pre>
|
||||
|
|
@ -1054,7 +1054,7 @@ example, consider this:
|
|||
<div class="code">
|
||||
<pre>
|
||||
struct Bar {
|
||||
int x[16];
|
||||
int x[16];
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1456,9 +1456,9 @@ Similarly, if you have a class like this,
|
|||
<pre>
|
||||
class Foo {
|
||||
public:
|
||||
Foo();
|
||||
Foo(const Foo &);
|
||||
...
|
||||
Foo();
|
||||
Foo(const Foo &);
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1693,11 +1693,11 @@ For example:
|
|||
%rename(Bar_spam) Bar::spam;
|
||||
|
||||
namespace Foo {
|
||||
int spam();
|
||||
int spam();
|
||||
}
|
||||
|
||||
namespace Bar {
|
||||
int spam();
|
||||
int spam();
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1886,19 +1886,19 @@ then SWIG transforms it into a set of low-level procedural wrappers. For example
|
|||
<div class="code">
|
||||
<pre>
|
||||
Foo *new_Foo() {
|
||||
return new Foo();
|
||||
return new Foo();
|
||||
}
|
||||
void delete_Foo(Foo *f) {
|
||||
delete f;
|
||||
delete f;
|
||||
}
|
||||
int Foo_x_get(Foo *f) {
|
||||
return f->x;
|
||||
return f->x;
|
||||
}
|
||||
void Foo_x_set(Foo *f, int value) {
|
||||
f->x = value;
|
||||
f->x = value;
|
||||
}
|
||||
int Foo_spam(Foo *f, int arg1) {
|
||||
return f->spam(arg1);
|
||||
return f->spam(arg1);
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1945,8 +1945,8 @@ ownership of the result. For example:
|
|||
<pre>
|
||||
class Foo {
|
||||
public:
|
||||
Foo();
|
||||
Foo bar();
|
||||
Foo();
|
||||
Foo bar();
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1975,9 +1975,9 @@ they came from. Therefore, the ownership is set to zero. For example:
|
|||
<pre>
|
||||
class Foo {
|
||||
public:
|
||||
...
|
||||
Foo *spam();
|
||||
...
|
||||
...
|
||||
Foo *spam();
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2011,8 +2011,8 @@ or global variable. For example, consider this interface:
|
|||
%module example
|
||||
|
||||
struct Foo {
|
||||
int value;
|
||||
Foo *next;
|
||||
int value;
|
||||
Foo *next;
|
||||
};
|
||||
|
||||
Foo *head = 0;
|
||||
|
|
@ -2465,9 +2465,9 @@ you might define a typemap like this:
|
|||
%module example
|
||||
|
||||
%typemap(in) int {
|
||||
if (Tcl_GetIntFromObj(interp, $input, &$1) == TCL_ERROR)
|
||||
return TCL_ERROR;
|
||||
printf("Received an integer : %d\n", $1);
|
||||
if (Tcl_GetIntFromObj(interp, $input, &$1) == TCL_ERROR)
|
||||
return TCL_ERROR;
|
||||
printf("Received an integer : %d\n", $1);
|
||||
}
|
||||
%inline %{
|
||||
extern int fact(int n);
|
||||
|
|
@ -2585,7 +2585,7 @@ like this:
|
|||
<div class="code">
|
||||
<pre>
|
||||
%typemap(out) int {
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj($1));
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj($1));
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3215,28 +3215,28 @@ helper functions to access arrays :
|
|||
|
||||
%inline %{
|
||||
double *new_double(int size) {
|
||||
return (double *) malloc(size*sizeof(double));
|
||||
return (double *) malloc(size*sizeof(double));
|
||||
}
|
||||
void delete_double(double *a) {
|
||||
free(a);
|
||||
free(a);
|
||||
}
|
||||
double get_double(double *a, int index) {
|
||||
return a[index];
|
||||
return a[index];
|
||||
}
|
||||
void set_double(double *a, int index, double val) {
|
||||
a[index] = val;
|
||||
a[index] = val;
|
||||
}
|
||||
int *new_int(int size) {
|
||||
return (int *) malloc(size*sizeof(int));
|
||||
return (int *) malloc(size*sizeof(int));
|
||||
}
|
||||
void delete_int(int *a) {
|
||||
free(a);
|
||||
free(a);
|
||||
}
|
||||
int get_int(int *a, int index) {
|
||||
return a[index];
|
||||
return a[index];
|
||||
}
|
||||
int set_int(int *a, int index, int val) {
|
||||
a[index] = val;
|
||||
a[index] = val;
|
||||
}
|
||||
%}
|
||||
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@
|
|||
<li><a href="#Typemaps_nn35">"memberin" typemap</a>
|
||||
<li><a href="#Typemaps_nn36">"varin" typemap</a>
|
||||
<li><a href="#Typemaps_nn37">"varout" typemap</a>
|
||||
<li><a href="#throws_typemap">"throws" typemap</a>
|
||||
<li><a href="#Typemaps_throws_typemap">"throws" typemap</a>
|
||||
</ul>
|
||||
<li><a href="#Typemaps_nn39">Some typemap examples</a>
|
||||
<ul>
|
||||
|
|
@ -89,6 +89,9 @@
|
|||
<li><a href="#Typemaps_runtime_type_checker_usage">Usage</a>
|
||||
</ul>
|
||||
<li><a href="#Typemaps_overloading">Typemaps and overloading</a>
|
||||
<ul>
|
||||
<li><a href="#Typemaps_typecheck_pointer">SWIG_TYPECHECK_POINTER precedence level and the typecheck typemap</a>
|
||||
</ul>
|
||||
<li><a href="#Typemaps_nn48">More about %apply and %clear</a>
|
||||
<li><a href="#Typemaps_nn47">Passing data between typemaps</a>
|
||||
<li><a href="#Typemaps_nn52">C++ "this" pointer</a>
|
||||
|
|
@ -2881,11 +2884,11 @@ The "varout" typemap is used to convert a C/C++ object to an object in the targe
|
|||
language when reading a C/C++ global variable. This is implementation specific.
|
||||
</p>
|
||||
|
||||
<H3><a name="throws_typemap">11.5.14 "throws" typemap</a></H3>
|
||||
<H3><a name="Typemaps_throws_typemap">11.5.14 "throws" typemap</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
The "throws" typemap is only used when SWIG parses a C++ method with an exception specification or has the <tt>%catches</tt> feature attached to the method.
|
||||
The "throws" typemap is only used when SWIG parses a C++ method with an exception specification or has the <tt>%catches</tt> feature attached to the method (see <a href="SWIGPlus.html#SWIGPlus_catches">Exception handling with %catches</a>).
|
||||
It provides a default mechanism for handling C++ methods that have declared the exceptions they will throw.
|
||||
The purpose of this typemap is to convert a C++ exception into an error or exception in the target language.
|
||||
It is slightly different to the other typemaps as it is based around the exception type rather than the type of a parameter or variable.
|
||||
|
|
@ -2898,13 +2901,19 @@ For example:
|
|||
PyErr_SetString(PyExc_RuntimeError, $1);
|
||||
SWIG_fail;
|
||||
%}
|
||||
void bar() throw (const char *);
|
||||
|
||||
// Either an exception specification on the method
|
||||
void bar() throw (const char *);
|
||||
|
||||
// Or a %catches feature attached to the method
|
||||
%catches(const char *) bar();
|
||||
void bar();
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
As can be seen from the generated code below, SWIG generates an exception handler
|
||||
with the catch block comprising the "throws" typemap content.
|
||||
As can be seen from the resulting generated code below, SWIG generates an exception handler
|
||||
when wrapping the <tt>bar</tt> function with the catch block comprising the "throws" typemap content.
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
|
|
@ -2912,8 +2921,7 @@ with the catch block comprising the "throws" typemap content.
|
|||
...
|
||||
try {
|
||||
bar();
|
||||
}
|
||||
catch(char const *_e) {
|
||||
} catch(char const *_e) {
|
||||
PyErr_SetString(PyExc_RuntimeError, _e);
|
||||
SWIG_fail;
|
||||
}
|
||||
|
|
@ -2922,8 +2930,8 @@ catch(char const *_e) {
|
|||
</div>
|
||||
|
||||
<p>
|
||||
Note that if your methods do not have an exception specification yet they do throw exceptions, SWIG cannot know how to deal with them.
|
||||
For a neat way to handle these, see the <a href="Customization.html#Customization_exception">Exception handling with %exception</a> section.
|
||||
Note that if your methods do not have an exception specification but they do throw exceptions and you are not using <tt>%catches</tt>, SWIG cannot know how to deal with them.
|
||||
Please also see the <a href="Customization.html#Customization_exception">Exception handling with %exception</a> section for another way to handle exceptions.
|
||||
</p>
|
||||
|
||||
<H2><a name="Typemaps_nn39">11.6 Some typemap examples</a></H2>
|
||||
|
|
@ -3904,9 +3912,9 @@ A fragment can use one or more additional fragments, for example:
|
|||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%fragment("<limits.h>", "header") {
|
||||
%#include <limits.h>
|
||||
}
|
||||
%fragment("<limits.h>", "header") %{
|
||||
#include <limits.h>
|
||||
%}
|
||||
|
||||
|
||||
%fragment("AsMyClass", "header", fragment="<limits.h>") {
|
||||
|
|
@ -3989,8 +3997,91 @@ Finally, you can force the inclusion of a fragment at any point in the generated
|
|||
</div>
|
||||
|
||||
<p>
|
||||
which is very useful inside a template class, for example.
|
||||
which, for example, is very useful inside a template class.
|
||||
Another useful case is when using <tt>%extend</tt> inside a class
|
||||
where the additional code in the <tt>%extend</tt> block depends on the contents of the fragment.
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%fragment("<limits.h>", "header") %{
|
||||
#include <limits.h>
|
||||
%}
|
||||
|
||||
struct X {
|
||||
...
|
||||
%extend {
|
||||
%fragment("<limits.h>");
|
||||
bool check(short val) {
|
||||
if (val < SHRT_MIN /*defined in <limits.h>*/) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
||||
<p>
|
||||
Forced inclusion of fragments can be used as a replacement for <a href="SWIG.html#SWIG_nn42">code insertion block</a>, ensuring the
|
||||
code block is only generated once.
|
||||
Consider the contents of FileA.i below which first uses a code insertion block and then a forced fragment inclusion to generate code:
|
||||
</p>
|
||||
<div class="code">
|
||||
<pre>
|
||||
// FileA.i
|
||||
%{
|
||||
#include <stdio.h>
|
||||
%}
|
||||
%fragment("<limits.h>");
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
and another file including the above:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
// FileB.i
|
||||
%include "FileA.i"
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
The resulting code in the wrappers for FileB.i is:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <limits.h>
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
A note of caution must be mentioned when using <tt>%fragment</tt> forced inclusion or code insertion blocks with <tt>%import</tt>.
|
||||
If <tt>%import</tt> is used instead:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
// FileC.i
|
||||
%import "FileA.i"
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
then nothing is generated in the resulting code in the wrappers for FileC.i.
|
||||
This is because <tt>%import</tt> is for collecting type information and does not result in any code
|
||||
being generated, see <a href="Preprocessor.html#Preprocessor_nn3">File Imports</a>.
|
||||
</p>
|
||||
|
||||
|
||||
</ol>
|
||||
|
||||
<p>
|
||||
|
|
@ -4671,7 +4762,8 @@ then the type is given a precedence higher than any other known precedence level
|
|||
|
||||
<div class="shell">
|
||||
<pre>
|
||||
example.i:18: Warning 467: Overloaded method foo(int) not supported (incomplete type checking rule - no precedence level in typecheck typemap for 'int').
|
||||
example.i:18: Warning 467: Overloaded method foo(int) not supported (incomplete type
|
||||
checking rule - no precedence level in typecheck typemap for 'int').
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -4696,10 +4788,112 @@ simply check the type of the first array element and use that to dispatch to the
|
|||
Subsequent "in" typemaps would then perform more extensive type-checking.
|
||||
</li>
|
||||
|
||||
<li>Make sure you read the section on overloading in the "<a href="SWIGPlus.html#SWIGPlus">SWIG and C++</a>" chapter.
|
||||
<li>Make sure you read the section on <a href="SWIGPlus.html#SWIGPlus_overloaded_methods">overloading</a> in the SWIG and C++ chapter.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<H3><a name="Typemaps_typecheck_pointer">11.13.1 SWIG_TYPECHECK_POINTER precedence level and the typecheck typemap</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
When it comes to overloading of a particular type passed by value, pointer or reference (const and non-const),
|
||||
a C++ compiler can disambiguate which overloaded function to call.
|
||||
However, SWIG effectively treats these as pointers in the target language and thus as equivalent types.
|
||||
For example, consider:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
class X { ... };
|
||||
void m(X const &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>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -423,8 +423,8 @@ Variable length arguments may be used in typemap specifications. For example:
|
|||
<div class="code">
|
||||
<pre>
|
||||
%typemap(in) (...) {
|
||||
// Get variable length arguments (somehow)
|
||||
...
|
||||
// Get variable length arguments (somehow)
|
||||
...
|
||||
}
|
||||
|
||||
%typemap(in) (const char *fmt, ...) {
|
||||
|
|
@ -529,8 +529,11 @@ like this:
|
|||
SWIG_fail;
|
||||
}
|
||||
pystr = PyUnicode_AsUTF8String(pyobj);
|
||||
if (!pystr) {
|
||||
SWIG_fail;
|
||||
}
|
||||
str = strdup(PyBytes_AsString(pystr));
|
||||
Py_XDECREF(pystr);
|
||||
Py_DECREF(pystr);
|
||||
%#else
|
||||
if (!PyString_Check(pyobj)) {
|
||||
PyErr_SetString(PyExc_ValueError, "Expected a string");
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>SWIG-3.0 Documentation</title>
|
||||
<title>SWIG-4.0 Documentation</title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
</head>
|
||||
<body bgcolor="#ffffff">
|
||||
<H1><a name="index">SWIG-3.0 Documentation</a></H1>
|
||||
<H1><a name="index">SWIG-4.0 Documentation</a></H1>
|
||||
|
||||
The SWIG documentation is available in one of the following formats.
|
||||
<ul>
|
||||
|
|
|
|||
|
|
@ -282,7 +282,7 @@ perl5_static_cpp: $(SRCDIR_SRCS)
|
|||
# -----------------------------------------------------------------
|
||||
|
||||
perl5_run:
|
||||
$(RUNTOOL) $(PERL) $(PERL5_SCRIPT) $(RUNPIPE)
|
||||
$(RUNTOOL) $(PERL) -I. $(PERL5_SCRIPT) $(RUNPIPE)
|
||||
|
||||
# -----------------------------------------------------------------
|
||||
# Version display
|
||||
|
|
@ -334,8 +334,8 @@ else
|
|||
SWIGOPTPY3 = -py3
|
||||
endif
|
||||
|
||||
PEP8 = @PEP8@
|
||||
PEP8_FLAGS = --ignore=E402,E501,E30,W291,W391
|
||||
PYCODESTYLE = @PYCODESTYLE@
|
||||
PYCODESTYLE_FLAGS = --ignore=E252,E30,E402,E501,E731,W291,W391
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
# Build a C dynamically loadable module
|
||||
|
|
@ -386,11 +386,11 @@ else
|
|||
PYSCRIPT = $(RUNME)3.py
|
||||
endif
|
||||
|
||||
PY2TO3 = 2to3 `2to3 -l | grep -v -E "Available|import$$" | awk '{print "-f "$$0}'`
|
||||
PY2TO3 = @PY2TO3@ `@PY2TO3@ -l | grep -v -E "Available|import$$" | awk '{print "-f "$$0}'`
|
||||
|
||||
python_run: $(PYSCRIPT)
|
||||
ifneq (,$(PEP8))
|
||||
$(COMPILETOOL) $(PEP8) $(PEP8_FLAGS) $(PYSCRIPT)
|
||||
ifneq (,$(PYCODESTYLE))
|
||||
$(COMPILETOOL) $(PYCODESTYLE) $(PYCODESTYLE_FLAGS) $(PYSCRIPT)
|
||||
endif
|
||||
env PYTHONPATH=$$PWD $(RUNTOOL) $(PYTHON) $(PYSCRIPT) $(RUNPIPE)
|
||||
|
||||
|
|
@ -1693,7 +1693,7 @@ r: $(SRCDIR_SRCS)
|
|||
ifneq ($(SRCDIR_SRCS),)
|
||||
$(CC) -g -c $(CPPFLAGS) $(CFLAGS) $(R_CFLAGS) $(SRCDIR_SRCS) $(INCLUDES)
|
||||
endif
|
||||
+( PKG_CPPFLAGS="$(CPPFLAGS) $(INCLUDES)" $(COMPILETOOL) $(R) CMD SHLIB -o $(LIBPREFIX)$(TARGET)$(SO) $(ISRCS) $(OBJS) > /dev/null )
|
||||
+( PKG_CPPFLAGS="$(CPPFLAGS) $(INCLUDES)" PKG_CFLAGS="$(CFLAGS)" $(COMPILETOOL) $(R) CMD SHLIB -o $(LIBPREFIX)$(TARGET)$(SO) $(ISRCS) $(OBJS) > /dev/null )
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
# Build a R dynamically loadable module (C++)
|
||||
|
|
@ -1703,7 +1703,7 @@ r_cpp: $(SRCDIR_CXXSRCS)
|
|||
ifneq ($(SRCDIR_CXXSRCS),)
|
||||
$(CXX) -g -c $(CPPFLAGS) $(CXXFLAGS) $(R_CFLAGS) $(SRCDIR_CXXSRCS) $(INCLUDES)
|
||||
endif
|
||||
+( PKG_CPPFLAGS="$(CPPFLAGS) $(INCLUDES)" $(COMPILETOOL) $(R) CMD SHLIB -o $(LIBPREFIX)$(TARGET)$(SO) $(RCXXSRCS) $(OBJS) > /dev/null )
|
||||
+( PKG_CPPFLAGS="$(CPPFLAGS) $(INCLUDES)" PKG_CXXFLAGS="$(CXXFLAGS)" $(COMPILETOOL) $(R) CMD SHLIB -o $(LIBPREFIX)$(TARGET)$(SO) $(RCXXSRCS) $(OBJS) > /dev/null )
|
||||
|
||||
# -----------------------------------------------------------------
|
||||
# Run R example
|
||||
|
|
|
|||
|
|
@ -36,6 +36,6 @@ func DeleteGoCallback(p GoCallback) {
|
|||
p.deleteCallback()
|
||||
}
|
||||
|
||||
func (p *goCallback) Run() {
|
||||
func (p *overwrittenMethodsOnCallback) Run() {
|
||||
fmt.Println("GoCallback.Run")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,5 +30,5 @@ f.enum_test(example.Foo.LUDICROUS);
|
|||
// enum value BLUE of enum color is accessed as property of cconst
|
||||
console.log("example.BLUE= " + example.BLUE);
|
||||
|
||||
// enum value LUDICROUS of enum Foo::speed is accessed as as property of cconst
|
||||
// enum value LUDICROUS of enum Foo::speed is accessed as property of cconst
|
||||
console.log("example.speed.LUDICROUS= " + example.Foo.LUDICROUS);
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ CEO=@(name) subclass(swigexample.Manager(name),'getPosition',@(self) "CEO");
|
|||
|
||||
# Create an instance of our employee extension class, CEO. The calls to
|
||||
# getName() and getPosition() are standard, the call to getTitle() uses
|
||||
# the director wrappers to call CEO.getPosition. e = CEO("Alice")
|
||||
# the director wrappers to call CEO.getPosition.
|
||||
|
||||
e = CEO("Alice");
|
||||
printf("%s is a %s\n",e.getName(),e.getPosition());
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ constants2
|
|||
extend
|
||||
funcptr
|
||||
import
|
||||
java
|
||||
multimap
|
||||
multiple_inheritance
|
||||
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()
|
||||
|
|
@ -5,7 +5,7 @@ CXXSRCS = example.cxx
|
|||
TARGET = example
|
||||
INTERFACE = example.i
|
||||
LIBS =
|
||||
SWIGOPT = -noproxy
|
||||
SWIGOPT =
|
||||
|
||||
check: build
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_run
|
||||
|
|
|
|||
|
|
@ -11,22 +11,22 @@ print " BLUE =" . BLUE;
|
|||
print " GREEN =" . GREEN;
|
||||
|
||||
print "\n*** Foo::speed ***";
|
||||
print " Foo_IMPULSE =" . Foo_IMPULSE;
|
||||
print " Foo_WARP =" . Foo_WARP;
|
||||
print " Foo_LUDICROUS =" . Foo_LUDICROUS;
|
||||
print " Foo::IMPULSE =" . Foo::IMPULSE;
|
||||
print " Foo::WARP =" . Foo::WARP;
|
||||
print " Foo::LUDICROUS =" . Foo::LUDICROUS;
|
||||
|
||||
print "\nTesting use of enums with functions\n";
|
||||
|
||||
enum_test(RED, Foo_IMPULSE);
|
||||
enum_test(BLUE, Foo_WARP);
|
||||
enum_test(GREEN, Foo_LUDICROUS);
|
||||
enum_test(RED, Foo::IMPULSE);
|
||||
enum_test(BLUE, Foo::WARP);
|
||||
enum_test(GREEN, Foo::LUDICROUS);
|
||||
enum_test(1234,5678);
|
||||
|
||||
print "\nTesting use of enum with class method\n";
|
||||
$f = new_Foo();
|
||||
$f = new Foo();
|
||||
|
||||
Foo_enum_test($f,Foo_IMPULSE);
|
||||
Foo_enum_test($f,Foo_WARP);
|
||||
Foo_enum_test($f,Foo_LUDICROUS);
|
||||
$f->enum_test(Foo::IMPULSE);
|
||||
$f->enum_test(Foo::WARP);
|
||||
$f->enum_test(Foo::LUDICROUS);
|
||||
|
||||
?>
|
||||
|
|
|
|||
|
|
@ -27,5 +27,6 @@
|
|||
# This code is inserted into example.php
|
||||
echo \"this was php code\\n\";
|
||||
"
|
||||
%pragma(php) version="1.5"
|
||||
|
||||
%pragma(php) phpinfo="php_info_print_table_start();"
|
||||
|
|
|
|||
|
|
@ -2,4 +2,5 @@
|
|||
|
||||
require "example.php";
|
||||
|
||||
echo "Version - " . ((new ReflectionExtension('example'))->getVersion());
|
||||
?>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ SRCS = example.c
|
|||
TARGET = example
|
||||
INTERFACE = example.i
|
||||
LIBS =
|
||||
SWIGOPT = -noproxy
|
||||
SWIGOPT =
|
||||
|
||||
check: build
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_run
|
||||
|
|
|
|||
|
|
@ -3,15 +3,15 @@
|
|||
require "example.php";
|
||||
|
||||
|
||||
$v = new_vector();
|
||||
vector_x_set($v,1.0);
|
||||
vector_y_set($v,2.0);
|
||||
vector_z_set($v,3.0);
|
||||
$v = new Vector();
|
||||
$v->x = 1.0;
|
||||
$v->y = 2.0;
|
||||
$v->z = 3.0;
|
||||
|
||||
$w = new_vector();
|
||||
vector_x_set($w,10.0);
|
||||
vector_y_set($w,11.0);
|
||||
vector_z_set($w,12.0);
|
||||
$w = new Vector();
|
||||
$w->x = 10.0;
|
||||
$w->y = 11.0;
|
||||
$w->z = 12.0;
|
||||
|
||||
echo "I just created the following vector\n";
|
||||
vector_print($v);
|
||||
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
echo "\nNow I'm going to add the vectors together\n";
|
||||
|
||||
$r = new_vector();
|
||||
$r = new Vector();
|
||||
vector_add($v, $w, $r);
|
||||
|
||||
vector_print($r);
|
||||
|
|
|
|||
|
|
@ -26,10 +26,10 @@
|
|||
echo "pt = ".pt_get(), point_print(pt_get()) , "\n";
|
||||
|
||||
/* Try to set the values of some global variables */
|
||||
$a = "42.14";
|
||||
$a = "42.14";
|
||||
|
||||
ivar_set($a);
|
||||
echo "a = $a\n";
|
||||
echo "a = $a\n";
|
||||
svar_set(-31000);
|
||||
lvar_set(65537);
|
||||
uivar_set(123456);
|
||||
|
|
|
|||
|
|
@ -27,5 +27,6 @@
|
|||
# This code is inserted into example.php
|
||||
echo \"this was php code\\n\";
|
||||
"
|
||||
%pragma(php) version="1.5"
|
||||
|
||||
%pragma(php) phpinfo="php_info_print_table_start();"
|
||||
|
|
|
|||
|
|
@ -2,4 +2,5 @@
|
|||
|
||||
require "example.php";
|
||||
|
||||
echo "Version - " . ((new ReflectionExtension('example'))->getVersion());
|
||||
?>
|
||||
|
|
|
|||
|
|
@ -26,10 +26,10 @@
|
|||
echo "pt = ".pt_get(), point_print(pt_get()) , "\n";
|
||||
|
||||
/* Try to set the values of some global variables */
|
||||
$a = "42.14";
|
||||
$a = "42.14";
|
||||
|
||||
ivar_set($a);
|
||||
echo "a = $a\n";
|
||||
echo "a = $a\n";
|
||||
svar_set(-31000);
|
||||
lvar_set(65537);
|
||||
uivar_set(123456);
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ functor
|
|||
import
|
||||
import_template
|
||||
import_packages
|
||||
java
|
||||
#libffi
|
||||
multimap
|
||||
operator
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ class CEO(example.Manager):
|
|||
|
||||
# Create an instance of our employee extension class, CEO. The calls to
|
||||
# getName() and getPosition() are standard, the call to getTitle() uses
|
||||
# the director wrappers to call CEO.getPosition. e = CEO("Alice")
|
||||
# the director wrappers to call CEO.getPosition.
|
||||
|
||||
e = CEO("Alice")
|
||||
print e.getName(), "is a", e.getPosition()
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import_packages_subdirs = \
|
|||
relativeimport2 \
|
||||
relativeimport3 \
|
||||
split_modules \
|
||||
namespace_pkg
|
||||
namespace_pkg \
|
||||
|
||||
|
||||
check: build
|
||||
|
|
@ -21,19 +21,19 @@ check: build
|
|||
mkdir -p `dirname $$file`; \
|
||||
cp "${SRCDIR}$$file" "$$file" || exit 1; \
|
||||
done; \
|
||||
fi; \
|
||||
fi
|
||||
for s in $(import_packages_subdirs); do \
|
||||
(cd $$s && $(MAKE) check); \
|
||||
(cd $$s && $(MAKE) check) || exit 1; \
|
||||
done
|
||||
|
||||
build:
|
||||
for s in $(import_packages_subdirs); do \
|
||||
(cd $$s && $(MAKE) SWIGOPT='$(SWIGOPT)' LIBS='$(LIBS)' build); \
|
||||
(cd $$s && $(MAKE) SWIGOPT='$(SWIGOPT)' LIBS='$(LIBS)' build) || exit 1; \
|
||||
done
|
||||
|
||||
static:
|
||||
for s in $(import_packages_subdirs); do \
|
||||
(cd $$s && $(MAKE) SWIGOPT='$(SWIGOPT)' LIBS='$(LIBS)' static); \
|
||||
(cd $$s && $(MAKE) SWIGOPT='$(SWIGOPT)' LIBS='$(LIBS)' static) || exit 1; \
|
||||
done
|
||||
|
||||
clean:
|
||||
|
|
@ -42,7 +42,7 @@ clean:
|
|||
for file in `cd $(SRCDIR) && find . -type f -name "*.py"`; do \
|
||||
rm -f "$$file" || exit 1; \
|
||||
done; \
|
||||
fi; \
|
||||
fi
|
||||
for s in $(import_packages_subdirs); do \
|
||||
(cd $$s && $(MAKE) clean); \
|
||||
(cd $$s && $(MAKE) clean) || exit 1; \
|
||||
done
|
||||
|
|
|
|||
|
|
@ -5,6 +5,10 @@ import os.path
|
|||
testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
|
||||
print "Testing " + testname + " - %module(package=...) + python 'import' in __init__.py"
|
||||
|
||||
if sys.version_info < (2, 5):
|
||||
print " Skipping test as Python version is < 2.5 and does not support relative import syntax: 'from . import x'"
|
||||
sys.exit(0)
|
||||
|
||||
if sys.version_info < (3, 0):
|
||||
import py2.pkg2
|
||||
print " Finished importing py2.pkg2"
|
||||
|
|
|
|||
|
|
@ -5,6 +5,10 @@ import os.path
|
|||
testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
|
||||
print "Testing " + testname + " - %module(package=...) + python 'import' in __init__.py"
|
||||
|
||||
if sys.version_info < (2, 5):
|
||||
print " Skipping test as Python version is < 2.5 and does not support relative import syntax: 'from . import x'"
|
||||
sys.exit(0)
|
||||
|
||||
if sys.version_info < (3, 0):
|
||||
import py2.pkg2
|
||||
print " Finished importing py2.pkg2"
|
||||
|
|
|
|||
|
|
@ -5,6 +5,10 @@ import os.path
|
|||
testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
|
||||
print "Testing " + testname + " - %module(package=...) + python 'import' in __init__.py"
|
||||
|
||||
if sys.version_info < (2, 5):
|
||||
print " Skipping test as Python version is < 2.5 and does not support relative import syntax: 'from . import x'"
|
||||
sys.exit(0)
|
||||
|
||||
if sys.version_info < (3, 0):
|
||||
import py2.pkg2
|
||||
print " Finished importing py2.pkg2"
|
||||
|
|
|
|||
|
|
@ -2,4 +2,5 @@
|
|||
|
||||
import robin
|
||||
|
||||
assert(robin.run() == "AWAY!")
|
||||
if not(robin.run() == "AWAY!"):
|
||||
raise RuntimeError("test failed")
|
||||
|
|
|
|||
|
|
@ -4,4 +4,5 @@ sys.path.insert(0, 'path1')
|
|||
|
||||
from brave import robin
|
||||
|
||||
assert(robin.run() == "AWAY!")
|
||||
if not(robin.run() == "AWAY!"):
|
||||
raise RuntimeError("test failed")
|
||||
|
|
|
|||
|
|
@ -6,4 +6,5 @@ sys.path.insert(0, 'path3')
|
|||
|
||||
from brave import robin
|
||||
|
||||
assert(robin.run() == "AWAY!")
|
||||
if not(robin.run() == "AWAY!"):
|
||||
raise RuntimeError("test failed")
|
||||
|
|
|
|||
|
|
@ -6,4 +6,5 @@ sys.path.insert(0, 'path3')
|
|||
|
||||
from brave import robin
|
||||
|
||||
assert(robin.run() == "AWAY!")
|
||||
if not(robin.run() == "AWAY!"):
|
||||
raise RuntimeError("test failed")
|
||||
|
|
|
|||
|
|
@ -5,6 +5,10 @@ import os.path
|
|||
testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
|
||||
print "Testing " + testname + " - %module(package=...) with -relativeimport"
|
||||
|
||||
if sys.version_info < (2, 5):
|
||||
print " Skipping test as Python version is < 2.5 and does not support relative import syntax: 'from . import x'"
|
||||
sys.exit(0)
|
||||
|
||||
if sys.version_info < (3, 0):
|
||||
import py2.pkg2.bar
|
||||
print " Finished importing py2.pkg2.bar"
|
||||
|
|
|
|||
|
|
@ -5,6 +5,10 @@ import os.path
|
|||
testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
|
||||
print "Testing " + testname + " - %module(package=...) + python 'import' in __init__.py"
|
||||
|
||||
if sys.version_info < (2, 5):
|
||||
print " Skipping test as Python version is < 2.5 and does not support relative import syntax: 'from . import x'"
|
||||
sys.exit(0)
|
||||
|
||||
if sys.version_info < (3, 0):
|
||||
import py2.pkg2.bar
|
||||
print " Finished importing py2.pkg2.bar"
|
||||
|
|
|
|||
|
|
@ -5,6 +5,10 @@ import os.path
|
|||
testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
|
||||
print "Testing " + testname + " - %module(package=...) with -relativeimport"
|
||||
|
||||
if sys.version_info < (2, 5):
|
||||
print " Skipping test as Python version is < 2.5 and does not support relative import syntax: 'from . import x'"
|
||||
sys.exit(0)
|
||||
|
||||
if sys.version_info < (3, 0):
|
||||
import py2.pkg2.bar
|
||||
print " Finished importing py2.pkg2.bar"
|
||||
|
|
|
|||
|
|
@ -6,21 +6,21 @@ subdirs = vanilla vanilla_split
|
|||
|
||||
check: build
|
||||
for s in $(subdirs); do \
|
||||
(cd $$s && $(MAKE) check); \
|
||||
(cd $$s && $(MAKE) check) || exit 1; \
|
||||
done
|
||||
|
||||
build:
|
||||
for s in $(subdirs); do \
|
||||
(cd $$s && $(MAKE) SWIGOPT='$(SWIGOPT)' LIBS='$(LIBS)' build); \
|
||||
(cd $$s && $(MAKE) SWIGOPT='$(SWIGOPT)' LIBS='$(LIBS)' build) || exit 1; \
|
||||
done
|
||||
|
||||
static:
|
||||
for s in $(subdirs); do \
|
||||
(cd $$s && $(MAKE) SWIGOPT='$(SWIGOPT)' LIBS='$(LIBS)' static); \
|
||||
(cd $$s && $(MAKE) SWIGOPT='$(SWIGOPT)' LIBS='$(LIBS)' static) || exit 1; \
|
||||
done
|
||||
|
||||
clean:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' python_clean
|
||||
for s in $(subdirs); do \
|
||||
(cd $$s && $(MAKE) clean); \
|
||||
(cd $$s && $(MAKE) clean) || exit 1; \
|
||||
done
|
||||
|
|
|
|||
|
|
@ -7,4 +7,5 @@ import pkg1.foo
|
|||
|
||||
print " Finished importing pkg1.foo"
|
||||
|
||||
assert(pkg1.foo.count() == 3)
|
||||
if not(pkg1.foo.count() == 3):
|
||||
raise RuntimeError("test failed")
|
||||
|
|
|
|||
|
|
@ -19,4 +19,6 @@ static:
|
|||
|
||||
clean:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' TARGET='foo' python_clean
|
||||
cd pkg1 && $(MAKE) -f $(TOP)/../Makefile SRCDIR='$(SRCDIR)' TARGET='foo' python_clean
|
||||
if test -d pkg1; then \
|
||||
cd pkg1 && $(MAKE) -f $(TOP)/../Makefile SRCDIR='$(SRCDIR)' TARGET='foo' python_clean; \
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -7,4 +7,5 @@ import pkg1.foo
|
|||
|
||||
print " Finished importing pkg1.foo"
|
||||
|
||||
assert(pkg1.foo.count() == 3)
|
||||
if not(pkg1.foo.count() == 3):
|
||||
raise RuntimeError("test failed")
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
PyObject *utf8str = PyUnicode_AsUTF8String(s);
|
||||
const char *cstr = PyBytes_AsString(utf8str);
|
||||
const char *cstr;
|
||||
if (!utf8str) {
|
||||
SWIG_fail;
|
||||
}
|
||||
cstr = PyBytes_AsString(utf8str);
|
||||
$2[i] = strdup(cstr);
|
||||
Py_DECREF(utf8str);
|
||||
}
|
||||
|
|
@ -72,6 +76,9 @@ extern int gcdmain(int argc, char *argv[]);
|
|||
SWIG_fail;
|
||||
}
|
||||
utf8str = PyUnicode_AsUTF8String($input);
|
||||
if (!utf8str) {
|
||||
SWIG_fail;
|
||||
}
|
||||
PyBytes_AsStringAndSize(utf8str, &cstr, &len);
|
||||
$1 = strncpy((char *)malloc(len+1), cstr, (size_t)len);
|
||||
$2 = (int)len;
|
||||
|
|
@ -105,6 +112,9 @@ extern int count(char *bytes, int len, char c);
|
|||
char *cstr;
|
||||
Py_ssize_t len;
|
||||
PyObject *utf8str = PyUnicode_AsUTF8String($input);
|
||||
if (!utf8str) {
|
||||
SWIG_fail;
|
||||
}
|
||||
PyBytes_AsStringAndSize(utf8str, &cstr, &len);
|
||||
$1 = strncpy((char *)malloc(len+1), cstr, (size_t)len);
|
||||
$2 = (int)len;
|
||||
|
|
|
|||
|
|
@ -52,14 +52,14 @@ print " Tring to set 'path'"
|
|||
try:
|
||||
example.cvar.path = "Whoa!"
|
||||
print "Hey, what's going on?!?! This shouldn't work"
|
||||
except:
|
||||
except Exception:
|
||||
print "Good."
|
||||
|
||||
print " Trying to set 'status'"
|
||||
try:
|
||||
example.cvar.status = 0
|
||||
print "Hey, what's going on?!?! This shouldn't work"
|
||||
except:
|
||||
except Exception:
|
||||
print "Good."
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ functor
|
|||
hashargs
|
||||
import
|
||||
import_template
|
||||
java
|
||||
mark_function
|
||||
multimap
|
||||
operator
|
||||
|
|
|
|||
|
|
@ -39,7 +39,11 @@ GC.start
|
|||
# C++ object
|
||||
ok = false
|
||||
begin
|
||||
puts tiger2.get_name
|
||||
# Let's stress the GC a bit, a single pass might not be enough.
|
||||
10.times {
|
||||
GC.start
|
||||
puts tiger2.get_name
|
||||
}
|
||||
rescue ObjectPreviouslyDeleted => error
|
||||
ok = true
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@
|
|||
|
||||
%typemap(in) (int nattributes, const char **names, const int *values) (VALUE keys_ary, int i, VALUE key, VALUE val) {
|
||||
Check_Type($input, T_HASH);
|
||||
$1 = NUM2INT(rb_funcall($input, rb_intern("size"), 0, NULL));
|
||||
$1 = NUM2INT(rb_funcall($input, rb_intern("size"), 0, Qnil));
|
||||
$2 = NULL;
|
||||
$3 = NULL;
|
||||
if ($1 > 0) {
|
||||
$2 = (char **) malloc($1*sizeof(char *));
|
||||
$3 = (int *) malloc($1*sizeof(int));
|
||||
keys_ary = rb_funcall($input, rb_intern("keys"), 0, NULL);
|
||||
keys_ary = rb_funcall($input, rb_intern("keys"), 0, Qnil);
|
||||
for (i = 0; i < $1; i++) {
|
||||
key = rb_ary_entry(keys_ary, i);
|
||||
val = rb_hash_aref($input, key);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
funcptr
|
||||
import
|
||||
java
|
||||
multimap
|
||||
operator
|
||||
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
|
||||
|
|
@ -47,6 +47,6 @@ testdir/README file.
|
|||
Further Documentation
|
||||
---------------------
|
||||
|
||||
There is documentation about the test-suite and how to use use it in
|
||||
There is documentation about the test-suite and how to use it in
|
||||
the SWIG documentation - Doc/Manual/Extending.html#Extending_test_suite.
|
||||
|
||||
|
|
|
|||
|
|
@ -133,6 +133,14 @@ typedef int Integer;
|
|||
void banana(S *a, const struct tagS *b, int c, Integer d) {}
|
||||
%}
|
||||
|
||||
// Check docs for a template type
|
||||
%inline %{
|
||||
template<typename X> struct T {
|
||||
T inout(T t) { return t; }
|
||||
};
|
||||
%}
|
||||
%template(TInteger) T<int>;
|
||||
|
||||
%inline %{
|
||||
#ifdef SWIGPYTHON_BUILTIN
|
||||
bool is_python_builtin() { return true; }
|
||||
|
|
@ -140,4 +148,3 @@ bool is_python_builtin() { return true; }
|
|||
bool is_python_builtin() { return false; }
|
||||
#endif
|
||||
%}
|
||||
|
||||
|
|
|
|||
160
Examples/test-suite/class_scope_namespace.i
Normal file
160
Examples/test-suite/class_scope_namespace.i
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
// Test a mix of forward class declarations, class definitions, using declarations and using directives.
|
||||
|
||||
%module class_scope_namespace
|
||||
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) H::HH;
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Space8::I_::II;
|
||||
|
||||
%inline %{
|
||||
struct A;
|
||||
namespace Space1 {
|
||||
namespace SubSpace1 {
|
||||
struct A {
|
||||
void aa(Space1::SubSpace1::A, SubSpace1::A, A) {}
|
||||
};
|
||||
void aaa(Space1::SubSpace1::A, SubSpace1::A, A) {}
|
||||
}
|
||||
}
|
||||
|
||||
namespace Space2 {
|
||||
struct B;
|
||||
}
|
||||
using Space2::B;
|
||||
#ifdef __clang__
|
||||
namespace Space2 {
|
||||
struct B {
|
||||
void bb(Space2::B, B) {}
|
||||
};
|
||||
}
|
||||
#else
|
||||
struct B {
|
||||
void bb(Space2::B, B) {}
|
||||
};
|
||||
#endif
|
||||
void bbb(Space2::B, B) {}
|
||||
|
||||
namespace Space3 {
|
||||
namespace SubSpace3 {
|
||||
struct C;
|
||||
struct D;
|
||||
}
|
||||
}
|
||||
struct C;
|
||||
struct D;
|
||||
namespace Space3 {
|
||||
struct C;
|
||||
struct SubSpace3::C {
|
||||
void cc(Space3::SubSpace3::C, SubSpace3::C) {}
|
||||
};
|
||||
using SubSpace3::D;
|
||||
struct SubSpace3::D {
|
||||
void dd(Space3::SubSpace3::D, SubSpace3::D, D) {}
|
||||
};
|
||||
void ccc(Space3::SubSpace3::C, SubSpace3::C) {}
|
||||
void ddd(Space3::SubSpace3::D, SubSpace3::D, D) {}
|
||||
}
|
||||
|
||||
namespace Space4 {
|
||||
namespace SubSpace4 {
|
||||
struct E;
|
||||
}
|
||||
}
|
||||
using namespace Space4;
|
||||
using SubSpace4::E;
|
||||
// Was added to incorrect namespace in swig-3.0.12
|
||||
struct SubSpace4::E {
|
||||
void ee(Space4::SubSpace4::E, SubSpace4::E, E) {}
|
||||
};
|
||||
void eee(Space4::SubSpace4::E, SubSpace4::E, E) {}
|
||||
|
||||
namespace Space5 {
|
||||
namespace SubSpace5 {
|
||||
namespace SubSubSpace5 {
|
||||
struct F;
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace Space5 {
|
||||
using namespace SubSpace5;
|
||||
using SubSubSpace5::F;
|
||||
// Was added to incorrect namespace in swig-3.0.12
|
||||
struct SubSubSpace5::F {
|
||||
void ff(Space5::SubSpace5::SubSubSpace5::F, SubSpace5::SubSubSpace5::F, SubSubSpace5::F, F) {}
|
||||
};
|
||||
void fff(Space5::SubSpace5::SubSubSpace5::F, SubSpace5::SubSubSpace5::F, SubSubSpace5::F, F) {}
|
||||
}
|
||||
|
||||
namespace Space6 {
|
||||
struct G;
|
||||
namespace SubSpace6 {
|
||||
struct G;
|
||||
}
|
||||
}
|
||||
namespace Space6 {
|
||||
struct SubSpace6::G {
|
||||
void gg(Space6::SubSpace6::G, SubSpace6::G) {}
|
||||
};
|
||||
void ggg(Space6::SubSpace6::G, SubSpace6::G) {}
|
||||
}
|
||||
|
||||
struct HH;
|
||||
struct H {
|
||||
struct HH {
|
||||
void hh(H::HH) {}
|
||||
};
|
||||
};
|
||||
void hhh(H::HH) {}
|
||||
|
||||
namespace Space8 {
|
||||
struct II;
|
||||
struct I_ {
|
||||
struct II {
|
||||
void ii(Space8::I_::II, I_::II) {}
|
||||
};
|
||||
};
|
||||
void iii(Space8::I_::II, I_::II) {}
|
||||
}
|
||||
|
||||
struct J;
|
||||
namespace Space9 {
|
||||
namespace SubSpace9 {
|
||||
struct J {
|
||||
void jj(Space9::SubSpace9::J, SubSpace9::J, J) {}
|
||||
};
|
||||
void jjj(Space9::SubSpace9::J, SubSpace9::J, J) {}
|
||||
}
|
||||
}
|
||||
|
||||
namespace Space10 {
|
||||
struct K;
|
||||
}
|
||||
namespace Space10 {
|
||||
namespace SubSpace10 {
|
||||
struct K {
|
||||
void kk(Space10::SubSpace10::K, SubSpace10::K, K) {}
|
||||
};
|
||||
void kkk(Space10::SubSpace10::K, SubSpace10::K, K) {}
|
||||
}
|
||||
}
|
||||
|
||||
namespace OtherSpace {
|
||||
struct L;
|
||||
struct M;
|
||||
}
|
||||
using OtherSpace::L;
|
||||
namespace Space11 {
|
||||
using OtherSpace::M;
|
||||
namespace SubSpace11 {
|
||||
struct L {
|
||||
void ll(Space11::SubSpace11::L, SubSpace11::L, L) {}
|
||||
};
|
||||
void lll(Space11::SubSpace11::L, SubSpace11::L, L) {}
|
||||
struct M {
|
||||
void mm(Space11::SubSpace11::M, SubSpace11::M, M) {}
|
||||
};
|
||||
void mmm(Space11::SubSpace11::M, SubSpace11::M, M) {}
|
||||
}
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
|
|
@ -89,7 +89,6 @@ CPP_TEST_BROKEN += \
|
|||
extend_variable \
|
||||
li_boost_shared_ptr_template \
|
||||
nested_private \
|
||||
overload_complicated \
|
||||
rename_camel \
|
||||
template_default_pointer \
|
||||
template_private_assignment \
|
||||
|
|
@ -99,7 +98,7 @@ CPP_TEST_BROKEN += \
|
|||
|
||||
# Broken C test cases. (Can be run individually using: make testcase.ctest)
|
||||
C_TEST_BROKEN += \
|
||||
tag_no_clash_with_variable
|
||||
tag_no_clash_with_variable \
|
||||
|
||||
# C++ test cases. (Can be run individually using: make testcase.cpptest)
|
||||
CPP_TEST_CASES += \
|
||||
|
|
@ -136,6 +135,7 @@ CPP_TEST_CASES += \
|
|||
char_binary \
|
||||
char_strings \
|
||||
chartest \
|
||||
class_scope_namespace \
|
||||
class_forward \
|
||||
class_ignore \
|
||||
class_scope_weird \
|
||||
|
|
@ -164,6 +164,7 @@ CPP_TEST_CASES += \
|
|||
cpp_typedef \
|
||||
curiously_recurring_template_pattern \
|
||||
default_args \
|
||||
default_arg_expressions \
|
||||
default_arg_values \
|
||||
default_constructor \
|
||||
defvalue_constructor \
|
||||
|
|
@ -181,6 +182,7 @@ CPP_TEST_CASES += \
|
|||
director_detect \
|
||||
director_enum \
|
||||
director_exception \
|
||||
director_exception_catches \
|
||||
director_extend \
|
||||
director_finalizer \
|
||||
director_frob \
|
||||
|
|
@ -192,6 +194,7 @@ CPP_TEST_CASES += \
|
|||
director_nspace_director_name_collision \
|
||||
director_overload \
|
||||
director_overload2 \
|
||||
director_ownership \
|
||||
director_pass_by_value \
|
||||
director_primitives \
|
||||
director_property \
|
||||
|
|
@ -246,6 +249,7 @@ CPP_TEST_CASES += \
|
|||
global_vars \
|
||||
grouping \
|
||||
ignore_parameter \
|
||||
import_fragments \
|
||||
import_nomodule \
|
||||
inherit \
|
||||
inherit_member \
|
||||
|
|
@ -262,9 +266,10 @@ CPP_TEST_CASES += \
|
|||
li_attribute \
|
||||
li_attribute_template \
|
||||
li_boost_shared_ptr \
|
||||
li_boost_shared_ptr_bits \
|
||||
li_boost_shared_ptr_template \
|
||||
li_boost_shared_ptr_attribute \
|
||||
li_boost_shared_ptr_bits \
|
||||
li_boost_shared_ptr_director \
|
||||
li_boost_shared_ptr_template \
|
||||
li_carrays_cpp \
|
||||
li_cdata_cpp \
|
||||
li_cpointer_cpp \
|
||||
|
|
@ -290,6 +295,7 @@ CPP_TEST_CASES += \
|
|||
multiple_inheritance_shared_ptr \
|
||||
name_cxx \
|
||||
name_warnings \
|
||||
namespace_chase \
|
||||
namespace_class \
|
||||
namespace_enum \
|
||||
namespace_extend \
|
||||
|
|
@ -314,6 +320,7 @@ CPP_TEST_CASES += \
|
|||
nested_template_base \
|
||||
nested_workaround \
|
||||
newobject1 \
|
||||
newobject3 \
|
||||
null_pointer \
|
||||
operator_overload \
|
||||
operator_overload_break \
|
||||
|
|
@ -322,6 +329,7 @@ CPP_TEST_CASES += \
|
|||
ordering \
|
||||
overload_arrays \
|
||||
overload_bool \
|
||||
overload_complicated \
|
||||
overload_copy \
|
||||
overload_extend \
|
||||
overload_method \
|
||||
|
|
@ -402,6 +410,7 @@ CPP_TEST_CASES += \
|
|||
template_basic \
|
||||
template_base_template \
|
||||
template_classes \
|
||||
template_class_reuse_name \
|
||||
template_const_ref \
|
||||
template_construct \
|
||||
template_templated_constructors \
|
||||
|
|
@ -417,6 +426,7 @@ CPP_TEST_CASES += \
|
|||
template_default_inherit \
|
||||
template_default_qualify \
|
||||
template_default_vw \
|
||||
template_empty_inherit \
|
||||
template_enum \
|
||||
template_enum_ns_inherit \
|
||||
template_enum_typedef \
|
||||
|
|
@ -433,6 +443,7 @@ CPP_TEST_CASES += \
|
|||
template_methods \
|
||||
template_namespace_forward_declaration \
|
||||
template_using_directive_and_declaration_forward \
|
||||
template_using_directive_typedef \
|
||||
template_nested \
|
||||
template_nested_typemaps \
|
||||
template_ns \
|
||||
|
|
@ -443,6 +454,7 @@ CPP_TEST_CASES += \
|
|||
template_ns_enum2 \
|
||||
template_ns_inherit \
|
||||
template_ns_scope \
|
||||
template_parameters_global_scope \
|
||||
template_partial_arg \
|
||||
template_partial_specialization \
|
||||
template_partial_specialization_typedef \
|
||||
|
|
@ -480,6 +492,7 @@ CPP_TEST_CASES += \
|
|||
throw_exception \
|
||||
typedef_array_member \
|
||||
typedef_class \
|
||||
typedef_classforward_same_name \
|
||||
typedef_funcptr \
|
||||
typedef_inherit \
|
||||
typedef_mptr \
|
||||
|
|
@ -500,6 +513,7 @@ CPP_TEST_CASES += \
|
|||
typemap_numinputs \
|
||||
typemap_template \
|
||||
typemap_template_parm_typedef \
|
||||
typemap_template_typedef \
|
||||
typemap_out_optimal \
|
||||
typemap_qualifier_strip \
|
||||
typemap_variables \
|
||||
|
|
@ -528,11 +542,12 @@ CPP_TEST_CASES += \
|
|||
varargs_overload \
|
||||
variable_replacement \
|
||||
virtual_destructor \
|
||||
virtual_derivation \
|
||||
virtual_poly \
|
||||
virtual_vs_nonvirtual_base \
|
||||
voidtest \
|
||||
wallkw \
|
||||
wrapmacro
|
||||
wrapmacro \
|
||||
|
||||
# C++11 test cases.
|
||||
CPP11_TEST_CASES += \
|
||||
|
|
@ -543,6 +558,7 @@ CPP11_TEST_CASES += \
|
|||
cpp11_default_delete \
|
||||
cpp11_delegating_constructors \
|
||||
cpp11_director_enums \
|
||||
cpp11_directors \
|
||||
cpp11_explicit_conversion_operators \
|
||||
cpp11_final_override \
|
||||
cpp11_function_objects \
|
||||
|
|
@ -554,6 +570,9 @@ CPP11_TEST_CASES += \
|
|||
cpp11_noexcept \
|
||||
cpp11_null_pointer_constant \
|
||||
cpp11_raw_string_literals \
|
||||
cpp11_ref_qualifiers \
|
||||
cpp11_ref_qualifiers_rvalue_unignore \
|
||||
cpp11_ref_qualifiers_typemaps \
|
||||
cpp11_result_of \
|
||||
cpp11_rvalue_reference \
|
||||
cpp11_rvalue_reference2 \
|
||||
|
|
@ -598,9 +617,7 @@ CPP_STD_TEST_CASES += \
|
|||
smart_pointer_inherit \
|
||||
template_typedef_fnc \
|
||||
template_type_namespace \
|
||||
template_opaque
|
||||
# li_std_list
|
||||
|
||||
template_opaque \
|
||||
|
||||
ifndef SKIP_CPP_STD_CASES
|
||||
CPP_TEST_CASES += ${CPP_STD_TEST_CASES}
|
||||
|
|
@ -619,6 +636,7 @@ C_TEST_CASES += \
|
|||
char_constant \
|
||||
const_const \
|
||||
constant_expr \
|
||||
default_args_c \
|
||||
empty_c \
|
||||
enums \
|
||||
enum_forward \
|
||||
|
|
@ -661,10 +679,11 @@ C_TEST_CASES += \
|
|||
string_simple \
|
||||
struct_rename \
|
||||
struct_initialization \
|
||||
typedef_classforward_same_name \
|
||||
typedef_struct \
|
||||
typemap_subst \
|
||||
union_parameter \
|
||||
unions
|
||||
unions \
|
||||
|
||||
|
||||
# Multi-module C++ test cases . (Can be run individually using make testcase.multicpptest)
|
||||
|
|
@ -675,7 +694,7 @@ MULTI_CPP_TEST_CASES += \
|
|||
packageoption \
|
||||
mod \
|
||||
template_typedef_import \
|
||||
multi_import
|
||||
multi_import \
|
||||
|
||||
# Custom tests - tests with additional commandline options
|
||||
wallkw.cpptest: SWIGOPT += -Wallkw
|
||||
|
|
|
|||
|
|
@ -14,26 +14,53 @@
|
|||
%template(VectorStdCplx) std::vector<std::complex<double> >;
|
||||
#endif
|
||||
|
||||
%inline
|
||||
%inline
|
||||
{
|
||||
std::complex<double> Conj(const std::complex<double>& a)
|
||||
std::complex<double> Conj(std::complex<double> a)
|
||||
{
|
||||
return std::conj(a);
|
||||
}
|
||||
}
|
||||
|
||||
std::complex<float> Conjf(const std::complex<float>& a)
|
||||
std::complex<float> Conjf(std::complex<float> a)
|
||||
{
|
||||
return std::conj(a);
|
||||
}
|
||||
}
|
||||
|
||||
#if 1
|
||||
std::vector<std::complex<double> > Copy_h(const std::vector<std::complex<double> >& a)
|
||||
std::vector<std::complex<double> > CopyHalf(std::vector<std::complex<double> > a)
|
||||
{
|
||||
std::vector<std::complex<double> > b(a.size()/2);
|
||||
std::copy(a.begin(), a.begin()+a.size()/2, b.begin());
|
||||
return b;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
using namespace std;
|
||||
|
||||
struct ComplexPair
|
||||
{
|
||||
std::complex<double> z1;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -43,7 +70,7 @@
|
|||
%{
|
||||
%}
|
||||
|
||||
%inline
|
||||
%inline
|
||||
{
|
||||
complex Conj(complex a)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -73,12 +73,18 @@ public:
|
|||
|
||||
%include "std_vector.i"
|
||||
|
||||
#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGPYTHON) || defined(SWIGR) || defined(SWIGOCTAVE) || defined(SWIGRUBY) || defined(SWIGJAVASCRIPT) || defined(SWIGSCILAB)
|
||||
#if defined(SWIGCSHARP) || defined(SWIGPYTHON) || defined(SWIGR) || defined(SWIGOCTAVE) || defined(SWIGRUBY) || defined(SWIGJAVASCRIPT) || defined(SWIGSCILAB)
|
||||
#define SWIG_GOOD_VECTOR
|
||||
%ignore std::vector<Space::Flow>::vector(size_type);
|
||||
%ignore std::vector<Space::Flow>::resize(size_type);
|
||||
#endif
|
||||
|
||||
#if defined(SWIGJAVA)
|
||||
#define SWIG_GOOD_VECTOR
|
||||
%ignore std::vector<Space::Flow>::vector(jint);
|
||||
%ignore std::vector<Space::Flow>::resize(jint);
|
||||
#endif
|
||||
|
||||
#if defined(SWIGTCL) || defined(SWIGPERL)
|
||||
#define SWIG_GOOD_VECTOR
|
||||
/* here, for languages with bad declaration */
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ struct SomeStruct {
|
|||
auto addAlternateMemberPtrConstParm(int x, int (SomeStruct::*mp)(int, int) const) const -> int;
|
||||
|
||||
virtual auto addFinal(int x, int y) const noexcept -> int final { return x + y; }
|
||||
virtual ~SomeStruct() = default;
|
||||
};
|
||||
|
||||
int SomeStruct::addNormal(int x, int y) { return x + y; }
|
||||
|
|
|
|||
|
|
@ -3,11 +3,17 @@
|
|||
*/
|
||||
%module cpp11_constexpr
|
||||
|
||||
|
||||
%inline %{
|
||||
#ifdef SWIG
|
||||
#define SWIGTESTCONST const
|
||||
#else
|
||||
#define SWIGTESTCONST
|
||||
#endif
|
||||
constexpr int AAA = 10;
|
||||
constexpr const int BBB = 20;
|
||||
constexpr int CCC() { return 30; }
|
||||
constexpr const int DDD() { return 40; }
|
||||
constexpr SWIGTESTCONST int DDD() { return 40; }
|
||||
|
||||
constexpr int XXX() { return 10; }
|
||||
constexpr int YYY = XXX() + 100;
|
||||
|
|
@ -17,7 +23,7 @@ struct ConstExpressions {
|
|||
static constexpr int KKK = 200;
|
||||
static const int LLL = 300;
|
||||
constexpr int MMM() { return 400; }
|
||||
constexpr const int NNN() { return 500; }
|
||||
constexpr SWIGTESTCONST int NNN() { return 500; }
|
||||
// Regression tests for support added in SWIG 3.0.4:
|
||||
static constexpr const int JJJ1 = 101;
|
||||
constexpr static int KKK1 = 201;
|
||||
|
|
|
|||
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