Merge branch 'master' into javalist
This commit is contained in:
commit
4db1300622
798 changed files with 26703 additions and 7774 deletions
153
.travis.yml
153
.travis.yml
|
|
@ -4,9 +4,16 @@ matrix:
|
|||
- compiler: clang
|
||||
os: linux
|
||||
env: SWIGLANG=
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- os: linux
|
||||
env: SWIGLANG= SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP11=1
|
||||
sudo: required
|
||||
|
|
@ -18,12 +25,18 @@ matrix:
|
|||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=csharp
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=d
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=go
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=go VER=1.5
|
||||
|
|
@ -32,21 +45,31 @@ matrix:
|
|||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=guile
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=java
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=javascript ENGINE=node
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=javascript ENGINE=jsc
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=javascript ENGINE=v8
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=lua
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=lua VER=5.3
|
||||
|
|
@ -54,77 +77,157 @@ matrix:
|
|||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=octave SWIGJOBS=-j2 # 3.2
|
||||
env: SWIGLANG=ocaml
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=octave SWIGJOBS=-j2 VER=3.8
|
||||
env: SWIGLANG=octave SWIGJOBS=-j2 # 3.8
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=octave SWIGJOBS=-j2 VER=4.0
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=octave SWIGJOBS=-j2 VER=4.2 CPP11=1
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=perl5
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=php
|
||||
env: SWIGLANG=php5
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=php VER=7.0
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=php VER=7.1
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=python VER=2.4
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=python VER=2.5
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=python VER=2.6
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=python # 2.7
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=python PY3=3 # 3.2
|
||||
env: SWIGLANG=python PY3=3 VER=3.2
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=python PY3=3 VER=3.3
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=python PY3=3 VER=3.4
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=python PY3=3 VER=3.5
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=python SWIG_FEATURES=-builtin VER=2.6
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=python SWIG_FEATURES=-builtin
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=python SWIG_FEATURES=-builtin PY3=3
|
||||
env: SWIGLANG=python SWIG_FEATURES=-builtin PY3=3 VER=3.4
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=python SWIG_FEATURES=-builtin PY3=3 VER=3.5
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=python SWIG_FEATURES=-builtin PY3=3 VER=3.5 SWIGOPTPY3=
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=python SWIG_FEATURES=-O
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=python SWIG_FEATURES=-classic
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=r
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=ruby
|
||||
env: SWIGLANG=ruby VER=1.9.3
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=ruby VER=2.0.0
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=ruby VER=2.3.0
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=scilab
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=tcl
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- os: linux
|
||||
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
|
||||
|
|
@ -133,10 +236,22 @@ matrix:
|
|||
env: SWIGLANG=python SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP11=1
|
||||
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
|
||||
|
|
@ -145,8 +260,17 @@ matrix:
|
|||
env: SWIGLANG=python SWIG_CC=gcc-6 SWIG_CXX=g++-6 CPP14=1
|
||||
sudo: required
|
||||
dist: trusty
|
||||
- os: osx
|
||||
env: SWIGLANG= SWIG_CC=gcc-4.2 SWIG_CXX=g++-4.2
|
||||
- os: linux
|
||||
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
|
||||
- compiler: gcc
|
||||
os: osx
|
||||
env: SWIGLANG=
|
||||
- compiler: clang
|
||||
os: osx
|
||||
env: SWIGLANG=
|
||||
|
|
@ -170,7 +294,7 @@ matrix:
|
|||
env: SWIGLANG=perl5
|
||||
- compiler: clang
|
||||
os: osx
|
||||
env: SWIGLANG=php
|
||||
env: SWIGLANG=php5
|
||||
- compiler: clang
|
||||
os: osx
|
||||
env: SWIGLANG=python
|
||||
|
|
@ -185,14 +309,22 @@ 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
|
||||
env: SWIGLANG=ocaml
|
||||
sudo: required
|
||||
dist: trusty
|
||||
# Not quite working yet
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=python SWIG_FEATURES=-O
|
||||
sudo: required
|
||||
dist: trusty
|
||||
before_install:
|
||||
- date -u
|
||||
- uname -a
|
||||
|
|
@ -233,6 +365,3 @@ script:
|
|||
- echo 'Cleaning...' && echo -en 'travis_fold:start:script.3\\r'
|
||||
- make check-maintainer-clean && ../../configure $CONFIGOPTS
|
||||
- echo -en 'travis_fold:end:script.3\\r'
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
|
|
|
|||
8
ANNOUNCE
8
ANNOUNCE
|
|
@ -1,8 +1,8 @@
|
|||
*** ANNOUNCE: SWIG 3.0.10 (in progress) ***
|
||||
*** ANNOUNCE: SWIG 4.0.0 (in progress) ***
|
||||
|
||||
http://www.swig.org
|
||||
|
||||
We're pleased to announce SWIG-3.0.10, 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.10.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.10.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.
|
||||
|
|
|
|||
|
|
@ -130,6 +130,7 @@ static void failed(void)
|
|||
exit(1);
|
||||
}
|
||||
args_add_prefix(orig_args, p);
|
||||
free(p);
|
||||
}
|
||||
|
||||
if (ccache_verbose) {
|
||||
|
|
@ -490,7 +491,9 @@ static void find_hash(ARGS *args)
|
|||
/* also include the hash of the compiler name - as some compilers
|
||||
use hard links and behave differently depending on the real name */
|
||||
if (st.st_nlink > 1) {
|
||||
hash_string(str_basename(args->argv[0]));
|
||||
char *path = str_basename(args->argv[0]);
|
||||
hash_string(path);
|
||||
free(path);
|
||||
}
|
||||
|
||||
hash_int(st.st_size);
|
||||
|
|
@ -523,6 +526,7 @@ static void find_hash(ARGS *args)
|
|||
input_base, tmp_string(),
|
||||
i_extension);
|
||||
x_asprintf(&path_stderr, "%s/tmp.cpp_stderr.%s", temp_dir, tmp_string());
|
||||
free(input_base);
|
||||
|
||||
if (!direct_i_file) {
|
||||
/* run cpp on the input file to obtain the .i */
|
||||
|
|
@ -781,6 +785,7 @@ static void find_compiler(int argc, char **argv)
|
|||
|
||||
/* support user override of the compiler */
|
||||
if ((path=getenv("CCACHE_CC"))) {
|
||||
free(base);
|
||||
base = x_strdup(path);
|
||||
}
|
||||
|
||||
|
|
@ -791,8 +796,10 @@ static void find_compiler(int argc, char **argv)
|
|||
stats_update(STATS_COMPILER);
|
||||
cc_log("could not find compiler (%s)\n", base);
|
||||
perror(base);
|
||||
free(base);
|
||||
exit(1);
|
||||
}
|
||||
free(base);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1076,6 +1083,7 @@ static void process_args(int argc, char **argv)
|
|||
if (strlen(p) < 2) {
|
||||
cc_log("badly formed dependency file %s\n", output_file);
|
||||
stats_update(STATS_ARGS);
|
||||
free(default_depfile_name);
|
||||
failed();
|
||||
return;
|
||||
}
|
||||
|
|
@ -1093,6 +1101,7 @@ static void process_args(int argc, char **argv)
|
|||
strcat(default_depfile_name, ".d");
|
||||
args_add(stripped_args, "-MF");
|
||||
args_add(stripped_args, default_depfile_name);
|
||||
free(default_depfile_name);
|
||||
}
|
||||
|
||||
if (!dependency_target_specified) {
|
||||
|
|
@ -1117,6 +1126,7 @@ static void process_args(int argc, char **argv)
|
|||
exit(1);
|
||||
}
|
||||
args_add_prefix(stripped_args, p);
|
||||
free(p);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1305,6 +1315,7 @@ static void setup_uncached_err(void)
|
|||
|
||||
if (putenv(buf) == -1) {
|
||||
cc_log("putenv failed\n");
|
||||
close(uncached_fd);
|
||||
stats_update(STATS_ERROR);
|
||||
failed();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -267,6 +267,7 @@ char *find_executable(const char *name, const char *exclude_name)
|
|||
}
|
||||
free(fname);
|
||||
}
|
||||
free(path);
|
||||
|
||||
return NULL;
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -138,7 +138,10 @@ static void stats_update_size(enum stats stat, size_t size, size_t numfiles)
|
|||
|
||||
memset(counters, 0, sizeof(counters));
|
||||
|
||||
if (lock_fd(fd) != 0) return;
|
||||
if (lock_fd(fd) != 0) {
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
/* read in the old stats */
|
||||
stats_read_fd(fd, counters);
|
||||
|
|
|
|||
|
|
@ -281,6 +281,7 @@ int unify_hash(const char *fname)
|
|||
fd = open(fname, O_RDONLY|O_BINARY);
|
||||
if (fd == -1 || fstat(fd, &st) != 0) {
|
||||
cc_log("Failed to open preprocessor output %s\n", fname);
|
||||
if (fd != -1) close(fd);
|
||||
stats_update(STATS_PREPROCESSOR);
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -289,12 +290,12 @@ int unify_hash(const char *fname)
|
|||
lines in preprocessor output. I have seen lines of over
|
||||
100k in length, so this is well worth it */
|
||||
map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
close(fd);
|
||||
if (map == (char *)-1) {
|
||||
cc_log("Failed to mmap %s\n", fname);
|
||||
stats_update(STATS_PREPROCESSOR);
|
||||
return -1;
|
||||
}
|
||||
close(fd);
|
||||
|
||||
/* pass it through the unifier */
|
||||
unify((unsigned char *)map, st.st_size);
|
||||
|
|
|
|||
|
|
@ -189,9 +189,11 @@ void copy_fd(int fd_in, int fd_out) {
|
|||
|
||||
while ((n = gzread(gz_in, buf, sizeof(buf))) > 0) {
|
||||
if (write(fd_out, buf, n) != n) {
|
||||
gzclose(gz_in);
|
||||
fatal("Failed to copy fd");
|
||||
}
|
||||
}
|
||||
gzclose(gz_in);
|
||||
}
|
||||
|
||||
static int _copy_file(const char *src, const char *dest, int mode) {
|
||||
|
|
@ -248,9 +250,11 @@ static int _copy_file(const char *src, const char *dest, int mode) {
|
|||
}
|
||||
|
||||
if (mode == COPY_TO_CACHE) {
|
||||
gz_out = gzdopen(dup(fd_out), "wb");
|
||||
int dup_fd_out = dup(fd_out);
|
||||
gz_out = gzdopen(dup_fd_out, "wb");
|
||||
if (!gz_out) {
|
||||
gzclose(gz_in);
|
||||
close(dup_fd_out);
|
||||
close(fd_out);
|
||||
free(tmp_name);
|
||||
return -1;
|
||||
|
|
@ -459,6 +463,7 @@ int create_cachedirtag(const char *dir)
|
|||
f = fopen(filename, "w");
|
||||
if (!f) goto error;
|
||||
if (fwrite(CACHEDIR_TAG, sizeof(CACHEDIR_TAG)-1, 1, f) != 1) {
|
||||
fclose(f);
|
||||
goto error;
|
||||
}
|
||||
if (fclose(f)) goto error;
|
||||
|
|
@ -485,7 +490,7 @@ void x_asprintf(char **ptr, const char *format, ...)
|
|||
}
|
||||
va_end(ap);
|
||||
|
||||
if (!ptr) fatal("out of memory in x_asprintf");
|
||||
if (!*ptr) fatal("out of memory in x_asprintf");
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
492
CHANGES
492
CHANGES
|
|
@ -2,6 +2,492 @@ SWIG (Simplified Wrapper and Interface Generator)
|
|||
|
||||
See the CHANGES.current file for changes in the current version.
|
||||
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.12 (27 Jan 2017)
|
||||
============================
|
||||
|
||||
2017-01-27: wsfulton
|
||||
[C#] #882 Fix missing filename in error messages when there is a problem
|
||||
writing out C# files.
|
||||
|
||||
2017-01-27: briancaine
|
||||
[Guile] #744 Fix compilation errors in Guile wrappers - regression
|
||||
introduced in swig-3.0.11.
|
||||
|
||||
2017-01-24: andrey-starodubtsev
|
||||
[Java] Apply #704 - director typemap improvements.
|
||||
Memory leak fixes, add support for "directorargout" typemap and
|
||||
add director support to typemaps.i.
|
||||
|
||||
2017-01-24: wsfulton
|
||||
Enhance %extend to extend a class with template constructors, eg:
|
||||
|
||||
struct Foo {
|
||||
%extend {
|
||||
template<typename T>
|
||||
Foo(int a, T b) {
|
||||
...
|
||||
}
|
||||
}
|
||||
};
|
||||
%template(Foo) Foo::Foo<double>;
|
||||
|
||||
2017-01-22: wsfulton
|
||||
Issue #876 Enhance %extend to extend a class with template methods, eg:
|
||||
|
||||
struct Foo {
|
||||
%extend {
|
||||
template<typename T>
|
||||
void do_stuff(int a, T b) {
|
||||
...
|
||||
}
|
||||
}
|
||||
};
|
||||
%template(do_stuff_inst) Foo::do_stuff<double>;
|
||||
|
||||
Similarly for static template methods.
|
||||
|
||||
2017-01-22: kwwette
|
||||
[Octave] add support for version 4.2
|
||||
- The Octave API now uses some C++11 features. It is recommended to use
|
||||
the mkoctfile program supplied by Octave to compile the SWIG-generated
|
||||
wrapper code, as mkoctfile will ensure the correct C++ compiler/options
|
||||
are used. Otherwise, the value of `mkoctfile -p CXX` should be parsed
|
||||
for any -std=* flags which might be present.
|
||||
- Octave has dropped support for << and >> operators, so SWIG now
|
||||
ignores them.
|
||||
- The Octave error() function now raises C++ exceptions to propagate
|
||||
Octave errors, so %exception directives may need to be modified.
|
||||
For convenience the SWIG_RETHROW_OCTAVE_EXCEPTIONS macro can be used
|
||||
to rethrow any Octave exceptions for Octave itself to handle, e.g.:
|
||||
|
||||
try {
|
||||
$action // may call error()
|
||||
}
|
||||
SWIG_RETHROW_OCTAVE_EXCEPTIONS // error() exceptions are rethrown
|
||||
catch(...) {
|
||||
... // all other exceptions
|
||||
}
|
||||
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
2017-01-16: wkalinin
|
||||
[C#] Fix #733 regression introduced in swig-3.0.9.
|
||||
Missing virtual function override in C# layer when using %import.
|
||||
|
||||
2017-01-16: fschlimb
|
||||
Fix #813 template symbol name lookup bug when typedef names are the same but in different
|
||||
namespaces.
|
||||
|
||||
2017-01-15: wsfulton
|
||||
[C# D Java]
|
||||
The SWIG library no longer uses the javatype, dtype or cstype typemaps, thereby
|
||||
completely freeing them up for users to use without having to replicate the library
|
||||
code that they previously added. The code previously generated by these typemaps
|
||||
has been replaced by the new %proxycode directive. Their use in the library code
|
||||
was fairly minimal:
|
||||
|
||||
C# cstype: std_array.i std_map.i std_vector.i
|
||||
D dtype: std_vector.i
|
||||
Java javatype: arrays_java.i
|
||||
|
||||
2017-01-14: wsfulton
|
||||
The %extend directive can now optionally support one of the 'class', 'struct' or 'union'
|
||||
keywords before the identifier name, for example:
|
||||
|
||||
struct X { ... };
|
||||
%extend struct X { ... }
|
||||
|
||||
Previously this had to specified as:
|
||||
|
||||
struct X { ... };
|
||||
%extend X { ... }
|
||||
|
||||
2017-01-13: wsfulton
|
||||
[C# D Java] Add new %proxycode directive which is a macro for %insert("proxycode").
|
||||
This is a way of adding pure C#/D/Java code into the appropriate proxy class, eg:
|
||||
|
||||
%extend Proxy2 {
|
||||
%proxycode %{
|
||||
public int proxycode2(int i) {
|
||||
return i+2;
|
||||
}
|
||||
%}
|
||||
}
|
||||
|
||||
%inline %{
|
||||
struct Proxy2 {};
|
||||
%}
|
||||
|
||||
There will then be a pure Java/C#/D method called proxycode2 in the Proxy2 class.
|
||||
|
||||
2016-12-31: ajrheading1
|
||||
Issue #860 - Remove use of std::unary_function and std::binary_function
|
||||
which is deprecated in C++11.
|
||||
|
||||
2016-12-30: olly
|
||||
[PHP7] Register internal 'swig_runtime_data_type_pointer' constant
|
||||
as "CONST_PERSISTENT" to avoid segmentation fault on module unload.
|
||||
Fixes #859 reported by Timotheus Pokorra. Thanks also to Javier Torres
|
||||
for a minimal reproducer.
|
||||
|
||||
Version 3.0.11 (29 Dec 2016)
|
||||
============================
|
||||
|
||||
2016-12-24: wsfulton
|
||||
[C#] Add %feature("csdirectordelegatemodifiers") to enable customization
|
||||
of the delegate access modifiers generated in director classes.
|
||||
Fixes issue #748.
|
||||
|
||||
2016-12-23: wsfulton
|
||||
[Python] Fix builtin "python:slot" feature failing for tp_hash when using
|
||||
hashfunc closure with a "Wrong type for hash function" for Python 2.
|
||||
Issue #843.
|
||||
|
||||
2016-12-21: joequamt
|
||||
Changed generation of functions so that only functions
|
||||
that end in _set generate accessor functions rather than
|
||||
looking for "set".
|
||||
Change generation of operators to not have underscores
|
||||
to start in R. Users need to provide custom names for these operator overloads.
|
||||
|
||||
2016-12-21: olly
|
||||
Fix isfinite() checks to work with all C++11 compilers.
|
||||
Fixes issues #615, #788 and #849.
|
||||
|
||||
2016-12-20: wsfulton
|
||||
%namewarn unnecessarily caused keyword warnings for non-instantiated template classes
|
||||
and duplicate warnings for instantiated template classes when keywords were used.
|
||||
Issue #845.
|
||||
|
||||
2016-12-18: ezralanglois
|
||||
[Python, Ruby, Octave] Memory leak fix on error in std::pair wrappers.
|
||||
Issue #851.
|
||||
|
||||
2016-12-18: wsfulton
|
||||
Zero initialize arrays when using %array_class and %array_functions.
|
||||
|
||||
2016-12-18: t-ikegami
|
||||
[Python] Fix #446
|
||||
Python %array_class of carrays.i failed with -builtin option.
|
||||
|
||||
2016-12-16: briancaine
|
||||
[Guile] Patch #744 Added support for Guile's native pointer functionality
|
||||
|
||||
2016-12-01: wsfulton
|
||||
[Python] Issue #769.
|
||||
Add optional moduleimport attribute to %module so that the
|
||||
default module import code can be overridden. See the "Searching for the wrapper module"
|
||||
documentation in Python.html. Example:
|
||||
|
||||
%module(moduleimport="import _foo") foo
|
||||
|
||||
$module also expands to the low-level C/C++ module name, so the following is the
|
||||
same as above
|
||||
|
||||
%module(moduleimport="import $module") foo
|
||||
|
||||
2016-11-30: olly
|
||||
[PHP] Add support for PHP7. PHP5's C extension API has changed
|
||||
substantially so you need to use -php7 to specify you want PHP7
|
||||
compatible wrappers. The default extension for generated wrappers
|
||||
is now .cxx (to match SWIG's default for every other language - to
|
||||
generate foo_wrap.cpp you can run SWIG with -cppext cpp). Fixes
|
||||
issue #571.
|
||||
|
||||
As part of this change, the language subdirectory for PHP5 has
|
||||
changed from "php" to "php5" - if you are making use of the search
|
||||
path feature where the language subdirectory of each directory
|
||||
is also searched, you'll need to update your bindings. A simple
|
||||
fix which works for older and newer SWIG is to add a symlink:
|
||||
ln -s php php5
|
||||
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
2016-11-30: olly
|
||||
[PHP] Only emit one copy of each distinct arginfo. Previously we
|
||||
emitted a separate one for every wrapped function, but typically
|
||||
many functions have the same number of parameters and combinations
|
||||
of parameters passed by reference or not.
|
||||
|
||||
This change significantly reduces both the size of the generated
|
||||
wrapper, and of the compiled PHP extension module (e.g. by ~6% for
|
||||
the stripped extension module for Xapian's PHP7 bindings).
|
||||
|
||||
2016-11-28: wsfulton
|
||||
Fix %rename override of wildcard %rename for templates. For example:
|
||||
|
||||
%rename(GlobalIntOperator) *::operator bool; // wildcard %rename
|
||||
|
||||
%rename(XIntOperator) X::operator bool; // fix now overrides first %rename above
|
||||
OR
|
||||
%rename(XIntOperator) X<int>::operator bool; // fix now overrides first %rename above
|
||||
|
||||
template<typename T> struct X {
|
||||
operator bool();
|
||||
...
|
||||
};
|
||||
%template(Xint) X<int>;
|
||||
|
||||
This also fixes %rename override of global %rename for templates. For example:
|
||||
|
||||
// Global rename to make all functions start with a lower case letter
|
||||
%rename("%(firstlowercase)s", %$isfunction ) "";
|
||||
%rename(woohoo) W::Woo; // fix now overrides above %rename
|
||||
|
||||
template<typename T> struct W {
|
||||
W Woo();
|
||||
...
|
||||
};
|
||||
%template(Wint) W<int>;
|
||||
|
||||
The above also introduces a possibly unexpected change. Many of the STL containers
|
||||
provided by SWIG use %rename to rename some methods, eg in std::vector, push_back
|
||||
is renamed to add in Java. Previously this intended rename did not happen when using
|
||||
using global %rename rules and the method would remain as push_back, but is now
|
||||
renamed to add. Some more info in issue #856.
|
||||
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
2016-11-26: m7thon
|
||||
[Python] Issue #709 - improved wrapping of division operators
|
||||
'from __future__ import division' now works in Python 2 whether or not the
|
||||
-py3 flag is used.
|
||||
|
||||
2016-11-12: joequant
|
||||
[R] Issue #697 - fix comma issue with overload methods
|
||||
|
||||
2016-11-12: joequant
|
||||
[R] Issue #555 - R runtime needs stdio.h
|
||||
|
||||
2016-11-02: wsfulton
|
||||
[Python] Issue #816 - fix compilation error when using -extranative and -builtin.
|
||||
|
||||
2016-11-02: liorgold
|
||||
Patch #741 - Add support for C++11 alias templates, see updated CPlusPlus11.html
|
||||
documentation.
|
||||
|
||||
2016-10-30: myd7349
|
||||
[C#] Patch #740 Add std_array.i for C# for wrapping std::array.
|
||||
|
||||
Patch also enhances std::vector<std::wstring> C# wrappers with additional functions
|
||||
(Contains, IndexOf, LastIndexOf and Remove).
|
||||
|
||||
2016-10-30: tobilau
|
||||
[Java] Fix wrappers for wstring parameters in director methods to cleanup local
|
||||
ref after director callback has finished.
|
||||
|
||||
2016-10-23: wsfulton
|
||||
[C#] Add missing csdirectorin VOID_INT_PTR and csdirectorout VOID_INT_PTR typemaps.
|
||||
|
||||
2016-10-23: jiulongw
|
||||
Patch #781 - Fix wrapping of C compound expressions containing char constants
|
||||
in quotes such as:
|
||||
|
||||
#define H_SUPPRESS_SCALING_MAGIC (('s'<<24) | ('u'<<16) | ('p'<<8) | 'p')
|
||||
|
||||
enum DifferentTypes {
|
||||
typecharcompound='A'+1,
|
||||
typecharcompound2='B' << 2
|
||||
};
|
||||
|
||||
2016-10-13: wsfulton
|
||||
[Python] Issue #808 - fix Python pickling and metaclass for builtin wrappers.
|
||||
|
||||
The metaclass (SwigPyObjectType) for SWIG objects was not defined in
|
||||
a way that let importlib successfully import the Python wrappers.
|
||||
The pickle module previously failed to pickle objects because it couldn't
|
||||
determine what module the SWIG wrapped objects were in.
|
||||
|
||||
2016-09-29: wsfulton
|
||||
[Allegrocl, CFFI, GO, Javascript, Ocaml, R, Scilab]
|
||||
Add missing support for the "ret" typemap in a few target languages.
|
||||
The documentation also now has info on the "ret" typemap.
|
||||
|
||||
2016-09-27: ahmed-usman
|
||||
[xml] Handle template parameters correctly.
|
||||
|
||||
2016-09-27: dontpanic92
|
||||
[Go] Fix argument names in inherited functions taking more than 8
|
||||
parameters. Fixes #795.
|
||||
|
||||
2016-09-26: smarchetto
|
||||
[Scilab] mlists that map pointers can be given a custom type name.
|
||||
|
||||
2016-09-25: wsfulton
|
||||
Patch #793 from q-p to expand exception handling to include std::bad_cast
|
||||
in std_except.i.
|
||||
|
||||
2016-09-24: olly
|
||||
[PHP] Fix code generated for feature("director:except") -
|
||||
previously the return value of call_user_function() was ignored and
|
||||
we checked an uninitialised value instead. Fixes #627. Based on
|
||||
patch from Sergey Seroshtan.
|
||||
|
||||
2016-09-22: wsfulton
|
||||
[Python] More flexible python builtin slots for overloaded C++ function.
|
||||
|
||||
The closure names used for builtin slots are mangled with their functype so
|
||||
that overloaded C++ method names can be used for multiple slots.
|
||||
For example:
|
||||
|
||||
%feature("python:slot", "mp_subscript", functype="binaryfunc") SimpleArray::__getitem__;
|
||||
%feature("python:slot", "sq_item", functype="ssizeargfunc") SimpleArray::__getitem__(Py_ssize_t n);
|
||||
|
||||
will generate closures:
|
||||
|
||||
SWIGPY_SSIZEARGFUNC_CLOSURE(_wrap_SimpleArray___getitem__) /* defines _wrap_SimpleArray___getitem___ssizeargfunc_closure */
|
||||
SWIGPY_BINARYFUNC_CLOSURE(_wrap_SimpleArray___getitem__) /* defines _wrap_SimpleArray___getitem___binaryfunc_closure */
|
||||
|
||||
Previously only one name was defined: _wrap_SimpleArray___getitem___closure.
|
||||
Hence the overloaded __getitem__ method can be used to support both mp_subscript and sq_item slots.
|
||||
|
||||
2016-09-17: wsfulton
|
||||
[Python] Fix iterators for containers of NULL pointers (or Python None) when using
|
||||
-builtin. Previously iteration would stop at the first element that was NULL.
|
||||
|
||||
2016-09-16: olly
|
||||
[Javascript] Fix SWIG_exception() macro to return from the current
|
||||
function. Fixes #789, reported by Julien Dutriaux.
|
||||
|
||||
2016-09-16: olly
|
||||
[PHP] Fix SWIG_exception() macro to return from the current function.
|
||||
Fixes #240, reported by Sergey Seroshtan.
|
||||
|
||||
2016-09-12: xypron
|
||||
[C#] Patch #786 Keyword rename to be CLS compliant by adding an underscore
|
||||
suffix instead of an underscore prefix to the C symbol name. Please use an explicit
|
||||
%rename to rename the symbol with a _ prefix if you want the old symbol name.
|
||||
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
2016-09-09: olly
|
||||
[Python] Fix import handling for Python 2.6 to work in a frozen
|
||||
application. Fixes #145, reported by Thomas Kluyver.
|
||||
|
||||
2016-09-02: smarchetto
|
||||
[Scilab] Pointers are mapped to mlist instead of tlist
|
||||
(mlist better for scilab overloading)
|
||||
|
||||
2016-09-02: olly
|
||||
[PHP] Fix "out" typemap for member function pointers and "in"
|
||||
typemap for char INPUT[ANY].
|
||||
|
||||
2016-09-01: wsfulton
|
||||
[Python] More efficient Python slicing.
|
||||
Call reserve for container types that support it to avoid repeated
|
||||
memory reallocations for new slices or slices that grow in size.
|
||||
|
||||
2016-09-01: wsfulton
|
||||
[Python] #771 - Make builtin types hashable by default.
|
||||
Default hash is the underlying C/C++ pointer. This matches up with testing for
|
||||
equivalence (Py_EQ in SwigPyObject_richcompare) which compares the pointers.
|
||||
|
||||
2016-08-22: wsfulton
|
||||
[Python] The following builtin slots can be customized like other slots via the
|
||||
"python:<x>" and "python:slot" features where <x> is the appropriate slot name:
|
||||
tp_allocs
|
||||
tp_bases
|
||||
tp_basicsize
|
||||
tp_cache
|
||||
tp_del
|
||||
tp_dealloc
|
||||
tp_flags
|
||||
tp_frees
|
||||
tp_getset
|
||||
tp_is_gc
|
||||
tp_maxalloc
|
||||
tp_methods
|
||||
tp_mro
|
||||
tp_new
|
||||
tp_next
|
||||
tp_prev
|
||||
tp_richcompare
|
||||
tp_subclasses
|
||||
tp_weaklist
|
||||
was_sq_ass_slice
|
||||
was_sq_slice
|
||||
|
||||
A few documentation improvements for slot customization.
|
||||
|
||||
2016-08-09: joequant
|
||||
[R] Patch #765 Fix extern "C" header includes for C++ code.
|
||||
|
||||
2016-08-05: olly
|
||||
[xml] Fix how the output filename is built to avoid problems when
|
||||
it contains the embedded strings ".c", ".cpp" or ".cxx".
|
||||
Fixes #540 reported by djack42.
|
||||
|
||||
2016-07-01: wsfulton
|
||||
Fix corner case of wrapping std::vector of T pointers where a pointer to a pointer of T
|
||||
also exists in the wrapped code. SF Bug 2359417 (967).
|
||||
|
||||
2016-06-26: wkalinin
|
||||
[Java, C#] Patch #681 Fix seg fault when ignoring nested classes.
|
||||
|
||||
2016-06-25: mromberg
|
||||
[Python] #711 Fix -castmode and conversion of signed and unsigned integer types.
|
||||
See 2015-12-23 CHANGES entry for details of these improvements when they were
|
||||
implemented for the default options (ie not using -castmode).
|
||||
|
||||
2016-06-25: ahnolds
|
||||
Patch #730 - Fix %implicitconv for overloaded functions when using
|
||||
-castmode or -fastdispatch options.
|
||||
|
||||
The result is that in all overload cases where there are multiple possibilities
|
||||
with the same number of arguments, the dispatch function will first check for
|
||||
exact (aka non implicit) matches, and then subsequently check for implicit
|
||||
casting matches. This was already happening in the normal dispatch situation,
|
||||
and in the -fastdispatch case two passes through the candidates were happening,
|
||||
just with SWIG_POINTER_IMPLICIT_CONV always set. After this patch, it is not set
|
||||
on the first pass, and then set on the second pass.
|
||||
|
||||
2016-06-25: liorgold
|
||||
Patch #727 - Add support for C++11 type aliasing.
|
||||
|
||||
Version 3.0.10 (12 Jun 2016)
|
||||
============================
|
||||
|
||||
2016-06-06: mromberg
|
||||
[Python] Patch #698. Add support for -relativeimport for python 2.7, so -py3 is no
|
||||
longer also required for relative import support.
|
||||
|
||||
2016-06-05: mromberg
|
||||
[Python] Patch #694 - Fix package import regressions introduced in swig-3.0.9.
|
||||
|
||||
1) The code in 3.0.9 did not fall back to 'import _foo' if 'import bar._foo' failed
|
||||
(assuming bar.foo was the main module). Every place _foo is imported now first tries
|
||||
it from the package where foo was found and if that fails tries _foo as a global module.
|
||||
|
||||
2) The separate block of Python code that injected code to pull in the attributes
|
||||
from _foo when -builtin is used made use of the -py3 switch to either do
|
||||
'from ._foo import *' or "from _foo import *". This block of code no longer does this
|
||||
and instead checks the Python version at runtime to switch between the two syntaxes.
|
||||
|
||||
In summary, swig-3.0.10 has been modified to ease the creation of wrapper modules
|
||||
that can be fully made part of a Python package. SWIG no longer
|
||||
assumes the dynamically linked C module is a global module.
|
||||
The dynamic module can now be placed into either the same package as the pure Python
|
||||
module or as a global module. Both locations are used by the Python wrapper to
|
||||
locate the C module.
|
||||
|
||||
However, this could cause a backwards incompatibility with some code
|
||||
that was relying on the ability of "from package import _module" to
|
||||
pull attributes out of the package directly. If your code populates a
|
||||
module (which is also a package) with attributes that are SWIG
|
||||
generated modules which were not loaded in a conventional way,
|
||||
swig-3.0.8 and earlier may have worked due to 'from package import
|
||||
_module' bypassing a real import and pulling your module in as an
|
||||
attribute. This will no longer work. Since this is not a common (or
|
||||
even recommended) practice, most folk should not be affected.
|
||||
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
2016-05-31: wsfulton
|
||||
Fix #690 - Smart pointer to %ignored class doesn't expose inherited methods.
|
||||
Regression introduced in swig-3.0.9.
|
||||
|
||||
Version 3.0.9 (29 May 2016)
|
||||
===========================
|
||||
|
|
@ -135,7 +621,7 @@ Version 3.0.9 (29 May 2016)
|
|||
|
||||
2016-03-01: olly
|
||||
Fix isfinite() check to work with GCC6. Fixes
|
||||
https://github.com/swig/swig/issues/615 reported by jplesnik.
|
||||
issue #615 reported by jplesnik.
|
||||
|
||||
2016-02-17: olly
|
||||
[Python] Add missing keywords 'as' and 'with' to pythonkw.swg.
|
||||
|
|
@ -192,7 +678,7 @@ Version 3.0.9 (29 May 2016)
|
|||
|
||||
2016-01-12: olly
|
||||
[Javascript] For v8 >= 4.3.0, use V8_MAJOR_VERSION.
|
||||
Fixes https://github.com/swig/swig/issues/561.
|
||||
Fixes issue 561.
|
||||
|
||||
2016-01-10: ahnolds
|
||||
Improved size_t and ptrdiff_t typemaps to support large values
|
||||
|
|
@ -783,7 +1269,7 @@ Version 3.0.3 (30 Dec 2014)
|
|||
2014-10-21: wsfulton
|
||||
Fix issue #242 - Use of the "kwargs" feature no longer automatically turns on the
|
||||
"compactdefaultargs" feature if the target language does not support kwargs.
|
||||
Only Java and Ruby support kwargs, so this affects all the other languages.
|
||||
This change affects all languages except Python and Ruby.
|
||||
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
|
|
|
|||
135
CHANGES.current
135
CHANGES.current
|
|
@ -1,7 +1,138 @@
|
|||
Below are the changes for the current release.
|
||||
See the CHANGES file for changes in older releases.
|
||||
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.10 (in progress)
|
||||
============================
|
||||
Version 4.0.0 (in progress)
|
||||
===========================
|
||||
|
||||
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-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:
|
||||
|
||||
typedef int (*FnPtr_td)(int, int);
|
||||
int do_op(int x, int y, FnPtr_td op);
|
||||
|
||||
2017-03-16: wsfulton
|
||||
Add support for member const function pointers such as:
|
||||
|
||||
int fn(short (Funcs::* parm)(bool)) const;
|
||||
|
||||
Also fix parsing of references/pointers and qualifiers to member
|
||||
pointers such as:
|
||||
|
||||
int fn(short (Funcs::* const parm)(bool));
|
||||
int fn(short (Funcs::* & parm)(bool));
|
||||
|
||||
2017-03-10: wsfulton
|
||||
Extend C++11 alternate function syntax parsing to support const and noexcept, such as:
|
||||
|
||||
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.
|
||||
|
||||
2017-02-10: tamuratak
|
||||
[Ruby] #883 - Add support for C++11 hash tables:
|
||||
std::unordered_map
|
||||
std::unordered_set
|
||||
std::unordered_multimap
|
||||
std::unordered_multiset
|
||||
|
||||
2017-02-08: jcsharp
|
||||
[C#] #887 Improve std::vector<T> wrapper constructors -
|
||||
Replace constructor taking ICollection with IEnumerable and also add IEnumerable<T>
|
||||
constructor to avoid the boxing and unboxing overhead of the original constructor,
|
||||
when the type parameter is a value type.
|
||||
|
|
|
|||
|
|
@ -1,788 +0,0 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
|
||||
<TITLE></TITLE>
|
||||
<META NAME="GENERATOR" CONTENT="OpenOffice.org 3.0 (Unix)">
|
||||
<META NAME="CREATED" CONTENT="20090712;16061100">
|
||||
<META NAME="CHANGED" CONTENT="20090817;17311900">
|
||||
<META NAME="Podatek 1" CONTENT="">
|
||||
<META NAME="Podatek 2" CONTENT="">
|
||||
<META NAME="Podatek 3" CONTENT="">
|
||||
<META NAME="Podatek 4" CONTENT="">
|
||||
<STYLE TYPE="text/css">
|
||||
<!--
|
||||
@page { margin: 2cm }
|
||||
H1 { margin-bottom: 0.21cm }
|
||||
H1.western { font-family: "Liberation Serif", serif }
|
||||
H1.cjk { font-family: "DejaVu Sans" }
|
||||
H1.ctl { font-family: "DejaVu Sans" }
|
||||
P { margin-bottom: 0.21cm }
|
||||
H2 { margin-bottom: 0.21cm }
|
||||
A:link { so-language: zxx }
|
||||
-->
|
||||
</STYLE>
|
||||
</HEAD>
|
||||
<BODY LANG="en-US" DIR="LTR">
|
||||
<H1 CLASS="western"><U>C++0x/C++11 support for SWIG</U></H1>
|
||||
<H1 CLASS="western">Summary</H1>
|
||||
<P>This is a technical overview of the C++0x/C++11 support for the Swig.
|
||||
This area of Swig is a work in progress. Initial C++0x/C++11 support for
|
||||
Swig was written during the Google Summer of Code 2009 period by
|
||||
Matevž Jekovec.</P>
|
||||
<H1 CLASS="western">SVN branch</H1>
|
||||
<P>branches/gsoc2009-matevz</P>
|
||||
<H1 CLASS="western">New C++11 features status</H1>
|
||||
<P>Wikipedia article: <A HREF="http://en.wikipedia.org/wiki/C++0x">http://en.wikipedia.org/wiki/C%2B%2B0x</A>
|
||||
</P>
|
||||
<H2>Rvalue reference and move semantics [done]</H2>
|
||||
<P>The Rvalues are used in practice to speed up the move operations
|
||||
on different containers.</P>
|
||||
<P>In the following example, we want to swap the given elements:</P>
|
||||
<PRE>template <class T> swap(T& a, T& b) {
|
||||
T tmp(a); // now we have two copies of a
|
||||
a = b; // now we have two copies of b
|
||||
b = tmp; // now we have two copies of tmp (aka a)
|
||||
}</PRE><P>
|
||||
This can now be solved using the new function std::move():</P>
|
||||
<PRE>template <class T> swap(T& a, T& b) {
|
||||
T tmp(std::move(a));
|
||||
a = std::move(b);
|
||||
b = std::move(tmp);
|
||||
}</PRE><P STYLE="margin-bottom: 0cm">
|
||||
For the move function to take effect, user needs to reimplement the
|
||||
move constructor (taking ClassType&& as an argument) and
|
||||
operator=(ClassType&&):</P>
|
||||
<PRE>class MyClass {
|
||||
MyClass(MyClass&& p) : ptr(p.ptr) {p.ptr = 0;}
|
||||
MyClass& operator=(MyClass&& p) {
|
||||
std::swap(ptr, p.ptr);
|
||||
return *this;
|
||||
}
|
||||
};</PRE><P>
|
||||
In practice, the Rvalues are used for temporaries (when passing the
|
||||
result of one function as an argument to another).</P>
|
||||
<P>Done: Added type&& to Swig parser. Added testcase
|
||||
cpp11_rvalue_reference.i. Operator && is treated the same as
|
||||
operator &. R11450</P>
|
||||
<P STYLE="margin-bottom: 0cm">Article:
|
||||
<A HREF="http://www.artima.com/cppsource/rvalue.html">http://www.artima.com/cppsource/rvalue.html</A></P>
|
||||
<H2>Generalized constant expressions [done]</H2>
|
||||
<P>In C++11 you can define functions as constant expressions.
|
||||
Functions need to return constant value in form "return expr",
|
||||
where expr is a constant expression.
|
||||
</P>
|
||||
<P>A keyword "constexpr" is introduced for this. eg.:
|
||||
constexpr int getNumber() { return 5; } const int MY_CONSTANT =
|
||||
getNumber();
|
||||
</P>
|
||||
<P>Constants are treated as normal variables in interpreted languages
|
||||
because they are not compiled into the executable. Java "final"
|
||||
constants are defined runtime as well. C++ constants need to be
|
||||
declared in the header file and defined in the implementation file,
|
||||
so swig doesn't need to know about the constant values when parsing
|
||||
the header file.
|
||||
</P>
|
||||
<P>Done: Added the “constexpr “ keyword to Swig. Added testcase
|
||||
cpp11_constexpr. R11322</P>
|
||||
<P>Problem: No compilers were known to support constexpr yet, so the
|
||||
testcase was temporarily commented out in common.mk.
|
||||
</P>
|
||||
<H2>Extern template [done]</H2>
|
||||
<P>Extern template forces the GCC compiler to not instantiate the
|
||||
template in the translation unit at that time. It's a feature
|
||||
specifically aimed at compilers to speed up the compilation process.
|
||||
</P>
|
||||
<P>Done: Added support for 'extern template class
|
||||
std::vector<MyClass>;'. Added testcase cpp11_template_explicit.
|
||||
R11385 , R11386</P>
|
||||
<H2>Initializer lists [done]</H2>
|
||||
<P>Initializer list is a new type in standard library:
|
||||
std::initializer_list<T>. New symbols {} are introduced for the
|
||||
initializer lists.
|
||||
</P>
|
||||
<P>One can now use:
|
||||
</P>
|
||||
<PRE> class A {
|
||||
public:
|
||||
A( std::initializer_list<int> );
|
||||
};
|
||||
A a1 = {1,2,3,4};</PRE><P>
|
||||
Languages like Java, C# and Python already support direct creation of
|
||||
lists natively.</P>
|
||||
<P>Problem: initializer_list cannot be treated as an ordinary list.
|
||||
The constructor containing initializer_list can only be accessed by
|
||||
assigning the value using the {} brackets. I also don't think there
|
||||
is a simple way to convert an ordinary list or a vector to the
|
||||
initializer_list.</P>
|
||||
<P>Done: Ignored the constructor having initializer_list as its
|
||||
argument. Show warning to the user. Added testcase
|
||||
cpp11_initializer_list. R11450</P>
|
||||
<P>Article:
|
||||
<A HREF="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1919.pdf">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1919.pdf</A></P>
|
||||
<H2>Uniform initialization [done]</H2>
|
||||
<P>The new C++11 standard will allow the following:</P>
|
||||
<PRE>struct IdString {
|
||||
std::string name;
|
||||
int identifier;
|
||||
};
|
||||
|
||||
IdString GetString() {
|
||||
return {"SomeName", 4}; //Note the lack of explicit type.
|
||||
}</PRE><P>
|
||||
The feature works exactly as it did now for POD types only (eg. int
|
||||
a[] = {1,2,3};). The following declarations are the same in the new
|
||||
C++11:</P>
|
||||
<PRE>IdString str1 = {„SomeName“, 4};
|
||||
IdString str2{„SomeName“, 4};</PRE><P>
|
||||
The new way of using uniform initialization allows the following:</P>
|
||||
<PRE>struct BasicStruct {
|
||||
int x;
|
||||
double y;
|
||||
};
|
||||
|
||||
struct AltStruct {
|
||||
AltStruct(int x, double y) : x_{x}, y_{y} {}
|
||||
|
||||
private:
|
||||
int x_;
|
||||
double y_;
|
||||
};
|
||||
|
||||
BasicStruct var1{5, 3.2}; // only fills the struct components
|
||||
AltStruct var2{2, 4.3}; // calls the constructor</PRE><P>
|
||||
The new syntax is specific to C++. Java, C# and scripting languages
|
||||
do not support this behaviour, but always need constructors. They
|
||||
support {} brackets for declaration of arrays as C does + they add
|
||||
support for creation of arrays on-the-fly (what C++11 introduced with
|
||||
this feature and more).</P>
|
||||
<P>Done: Added syntax for {} member initialization in class
|
||||
constructor. Added testcase cpp11_uniform_initialization. R11413</P>
|
||||
<H2>Type inference [partially done]</H2>
|
||||
<P>A new keyword 'auto' is introduced in C++11:</P>
|
||||
<PRE>auto a1 = 100;
|
||||
auto a2 = myFunc();</PRE><P>
|
||||
The type of a1 and a2 is automatically determined according to the
|
||||
initialization value during the semantic phase of the compiler.</P>
|
||||
<P>Another macro 'decltype()' is introduced. The macro takes the
|
||||
concrete object as an argument and returns its type. User could use
|
||||
this as:</P>
|
||||
<PRE>int i = 100;
|
||||
decltype(i) j = 200; // decltype(i) = int</PRE><P STYLE="margin-bottom: 0cm">
|
||||
Calling operators are allowed as well:</P>
|
||||
<PRE STYLE="margin-bottom: 0.5cm">decltype(i+j) k = 300;</PRE><P>
|
||||
Done: Added support for decltype() syntax. Test cases for normal
|
||||
decltype members and alternate function members work fine. Currently
|
||||
only syntax in form decltype(variable name) work. No support for
|
||||
custom expresions eg. decltype(i+j) yet. R11525</P>
|
||||
<P>TODO: William proposed to support the hidden variables as well
|
||||
(ones not parsed by Swig and added to symbol table). This also allows
|
||||
Swig to parse custom expressions like decltype(i+j). The idea is to
|
||||
introduce a new SwigType for this.</P>
|
||||
<H2>Range-based for-loop [ignored]</H2>
|
||||
<P>This feature is always present inside the implementation block
|
||||
only.
|
||||
</P>
|
||||
<H2>Lambda functions and expressions [done]</H2>
|
||||
<P>C++11 introduces lambda functions defined as:</P>
|
||||
<PRE STYLE="margin-bottom: 0.5cm">[](int x, int y) -> int { return x + y; }</PRE><P>
|
||||
If the lambda function contains a single return statement only or the
|
||||
function doesn't return any type, the return type '->' can be
|
||||
omitted. Lambda functions are function objects.</P>
|
||||
<P>The following example prints the number of items stored in a list:</P>
|
||||
<PRE>std::vector<int> someList;
|
||||
int total = 0;
|
||||
std::for_each( someList.begin(), someList.end(), [&total](int x) {total += x} );
|
||||
std::cout << total;</PRE><P>
|
||||
Parameters inside the [] are the visible parameters of the lambda
|
||||
functions. These can be & (references), = (copies), variable name
|
||||
(variable copy), &variable name (variable reference) or this
|
||||
(copy of the current object).</P>
|
||||
<P>Lambda functions can be stored using:</P>
|
||||
<PRE STYLE="margin-bottom: 0.5cm">auto myLambdaFunc = [this]() { this->SomePrivateMemberFunction() };</PRE><P>
|
||||
Proposal: Lambda functions are most commonly used inside the function
|
||||
block to quickly define how the sort, find and similar functions
|
||||
should work (the other way would be overriding a class – the Java
|
||||
style). The latest GCC does not support lambda functions yet so it is
|
||||
difficult to test the feature once implemented. I would implement the
|
||||
syntax support for this feature, but produce no wrapper code. Lambda
|
||||
functions still work inside the function block though.</P>
|
||||
<P>Article:
|
||||
<A HREF="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2550.pdf">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2550.pdf</A></P>
|
||||
<P>Done: Added syntax support for the lambda functions. Added
|
||||
testcase cpp11_lambda_functions.i. R11491, R11492</P>
|
||||
<H2>Alternate function syntax [done]</H2>
|
||||
<P>The problem with decltype() is that the parameters need to be
|
||||
defined before the decltype. The following syntax is not valid,
|
||||
because lhs and rhs hasn't been defined at the time of decltype:</P>
|
||||
<PRE>template< typename LHS, typename RHS>
|
||||
decltype(lhs+rhs) AddingFunc(const LHS &lhs, const RHS &rhs) {return lhs + rhs;} //Not legal C++11</PRE><P>
|
||||
The solution C++11 offers is the combination of the 'auto' keyword
|
||||
before and '-> rettype' after the function declaration:</P>
|
||||
<PRE>template< typename LHS, typename RHS>
|
||||
auto AddingFunc(const LHS &lhs, const RHS &rhs) -> decltype(lhs+rhs) {return lhs + rhs;}</PRE><P>
|
||||
The new syntax only makes the job for the C++ compilers easier when
|
||||
parsing such functions. The new syntax can be used for ordinary
|
||||
functions as well:</P>
|
||||
<PRE>struct SomeStruct {
|
||||
auto FuncName(int x, int y) -> int;
|
||||
};
|
||||
|
||||
auto SomeStruct::FuncName(int x, int y) -> int {
|
||||
return x + y;
|
||||
}</PRE><P>
|
||||
Done: Added support for the 'auto' return type. Added support for the
|
||||
'-> type' after the funtion declaration. Added testcases
|
||||
cpp11_alternate_function_syntax.i and
|
||||
cpp11_alternate_function_syntax_runme.py. R11414</P>
|
||||
<H2>Concepts, Axioms [ignored]</H2>
|
||||
<P>In C++ there is a common problem when you use a template in the
|
||||
class which doesn't support all the operations the functions in the
|
||||
class actually do on the type. Compiler errors are usually very long
|
||||
and unreadable. C++11 adds support for the "concepts". The
|
||||
idea is to define what operations and attributes should the template
|
||||
have. In contrast to class inheritance and polimorphism, all lookups
|
||||
are done in compile-time.
|
||||
</P>
|
||||
<P>Basic syntax (note LessThanComparable<A HREF="http://www.dabeaz.com/cgi-bin/wiki.pl?action=change1&id=LessThanComparable">?</A>
|
||||
instead of "class" or "typename"):
|
||||
</P>
|
||||
<PRE> template<LessThanComparable<A HREF="http://www.dabeaz.com/cgi-bin/wiki.pl?action=change1&id=LessThanComparable">?</A> T>
|
||||
const T& min(const T &x, const T &y) {
|
||||
return y < x ? y : x;
|
||||
}</PRE><P>
|
||||
Extended syntax (requires conditions are separated with &&,
|
||||
|| or !):
|
||||
</P>
|
||||
<PRE> template< typename T> requires LessThanComparable<A HREF="http://www.dabeaz.com/cgi-bin/wiki.pl?action=change1&id=LessThanComparable">?</A><T>
|
||||
const T& min(const T &x, const T &y) {
|
||||
return y < x ? y : x;
|
||||
}</PRE><P>
|
||||
Definition of the concepts:
|
||||
</P>
|
||||
<PRE> concept LessThanComparable<A HREF="http://www.dabeaz.com/cgi-bin/wiki.pl?action=change1&id=LessThanComparable">?</A>< typename T > {
|
||||
bool operator<(T,T);
|
||||
requires GreaterThanComparable<A HREF="http://www.dabeaz.com/cgi-bin/wiki.pl?action=change1&id=GreaterThanComparable">?</A><T>;
|
||||
typename value_type;
|
||||
typename reference;
|
||||
};</PRE><P>
|
||||
Concept maps allow usage of a specific type:
|
||||
</P>
|
||||
<PRE> template< typename T>
|
||||
concept_map InputIterator<A HREF="http://www.dabeaz.com/cgi-bin/wiki.pl?action=change1&id=InputIterator">?</A><T*> {
|
||||
typedef T value_type ;
|
||||
typedef T& reference ;
|
||||
typedef T* pointer ;
|
||||
typedef std::ptrdiff_t difference_type ;
|
||||
};</PRE><P>
|
||||
Concept maps can act as mini-types, with function definitions and
|
||||
other constructs commonly associated with classes:
|
||||
</P>
|
||||
<PRE> concept Stack< typename X> {
|
||||
typename value_type;
|
||||
void push(X&, const value_type&);
|
||||
void pop(X&);
|
||||
value_type top(const X&);
|
||||
bool empty(const X&);
|
||||
};
|
||||
template< typename T>
|
||||
concept_map Stack<std::vector<T> > {
|
||||
typedef T value_type;
|
||||
void push(std::vector<T>& v, const T& x) { v.push_back(x); }
|
||||
void pop(std::vector<T>& v) { v.pop_back(); }
|
||||
T top(const std::vector<T>& v) { return v.back(); }
|
||||
bool empty(const std::vector<T>& v) { return v.empty(); }
|
||||
};</PRE><P>
|
||||
Axioms are a facility pertaining to concepts supplied by C++11 to
|
||||
express the semantic properties of concepts. For example, the concept
|
||||
Semigroup can be defined with an axiom Associativity as:
|
||||
</P>
|
||||
<PRE> concept Semigroup< typename Op, typename T> : CopyConstructible<A HREF="http://www.dabeaz.com/cgi-bin/wiki.pl?action=change1&id=CopyConstructible">?</A><T> {
|
||||
T operator()(Op, T, T);
|
||||
axiom Associativity(Op op, T x, T y, T z) {
|
||||
op(x, op(y, z)) == op(op(x, y), z);
|
||||
}
|
||||
};</PRE><P>
|
||||
Axioms are more like hints to the compiler to speed-up the process of
|
||||
compilation.
|
||||
</P>
|
||||
<P>Ignored: Concepts and axioms were removed from the C++11 standard.
|
||||
</P>
|
||||
<H2>Object construction improvement [done]</H2>
|
||||
<P>This feature allows classes constructors to call other
|
||||
constructors with different arguments (similar to Java and C#
|
||||
behaviour).
|
||||
</P>
|
||||
<P>The syntax is as follows:
|
||||
</P>
|
||||
<PRE> class SomeType {
|
||||
int number;
|
||||
public:
|
||||
SomeType(int newNumber) : number(newNumber) {}
|
||||
SomeType() : SomeType(42) {}
|
||||
};</PRE><P>
|
||||
Also when using the inheritance, the feature introduces inheritance
|
||||
of all superclass constructors without being defined separately in
|
||||
the inherited class:
|
||||
</P>
|
||||
<PRE> class BaseClass {
|
||||
public:
|
||||
BaseClass(int iValue);
|
||||
};
|
||||
class DerivedClass: public BaseClass {
|
||||
public:
|
||||
using BaseClass::BaseClass; // Adds DerivedClass(int) constructor
|
||||
};</PRE><P>
|
||||
Swig already correctly parses and produces the correct wrapper for
|
||||
the “using” keyword.</P>
|
||||
<P>Done: Added testcase cpp11_constructors.i which covers both
|
||||
constructor delegation and constructor inheritance. R11532</P>
|
||||
<P>Problem: Constructor delegation and constructor inheritance is not
|
||||
supported by any compiler yet, so it's impossible to try and test
|
||||
this feature.</P>
|
||||
<H2>Null pointer constant [done]</H2>
|
||||
<P>nullptr is part of the standard library.
|
||||
</P>
|
||||
<P>It's defined as typedef decltype(nullptr) nullptr_t;
|
||||
</P>
|
||||
<P>nullptr_t is defined in <cstddef>.
|
||||
</P>
|
||||
<P>As far as the C++ is compatible with 0 as the pointer value, swig
|
||||
values will work for the C++. And the other way around, nullptr
|
||||
behaves as the ordinary pointer (false, if empty, true, if not
|
||||
empty), so it's ok for swig to compare it.</P>
|
||||
<P>Done: Written a testcase cpp11_null_pointer_constant.i and
|
||||
cpp11_null_pointer_constant_runme.py to prove the nullptr
|
||||
functionality. R11484</P>
|
||||
<H2>Strongly typed enumerations [partially done]</H2>
|
||||
<P>C++11 introduces a new syntax for strongly typed enum declaration:
|
||||
</P>
|
||||
<PRE> enum class Enumeration {
|
||||
Val1,
|
||||
Val2,
|
||||
Val3 = 100,
|
||||
Val4 /* = 101 */
|
||||
};</PRE><P>
|
||||
Typing if (Val4 == 101) will result in compilation error.
|
||||
</P>
|
||||
<P>The enum itself can now be explicitely of type int, long, unsigned
|
||||
int etc.:
|
||||
</P>
|
||||
<PRE STYLE="margin-bottom: 0.5cm"> enum class Enum2 : unsigned int {Val1, Val2};</PRE><P>
|
||||
And it can be forward declared as well:
|
||||
</P>
|
||||
<PRE> enum Enum1; //Illegal in C++ and C++11; no size is explicitly specified.
|
||||
enum Enum2 : unsigned int; //Legal in C++11.
|
||||
enum class Enum3; //Legal in C++11, because enum class declarations have a default type of "int".
|
||||
enum class Enum4: unsigned int; //Legal C++11.
|
||||
enum Enum2 : unsigned short; //Illegal in C++11, because Enum2 was previously declared with a different type.</PRE><P>
|
||||
Done: Added syntax 'enum class Name' and forward declarators 'enum
|
||||
Name : inherited type' or 'enum class Name : inherited type' in
|
||||
R11449.</P>
|
||||
<P>TODO: Add semantic support for enum elements not clashing with
|
||||
enum elements in other enum classes. See cpp11_strongly_typed_enums.i
|
||||
warnings.</P>
|
||||
<P>Problem: Swig currently doesn't support nested classes. This
|
||||
feature should be implemented using a new nested class when using
|
||||
“enum class” with a single anonymous “enum {elements}”
|
||||
element inside. For example:</P>
|
||||
<PRE STYLE="margin-bottom: 0.5cm">class A { enum class EA { a,b,c,d }; };</PRE><P>
|
||||
should be mapped to</P>
|
||||
<PRE STYLE="margin-bottom: 0.5cm">class A { class EA { enum {a,b,c,d}; }; };</PRE><H2>
|
||||
Angle bracket [done]</H2>
|
||||
<P>Support for right angled brackets was implemented using the
|
||||
following article as a base:
|
||||
<A HREF="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1757.html">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1757.html</A>
|
||||
</P>
|
||||
<P>Done: Added support for angle brackets. Used the preferred
|
||||
"Approach 1". Added a testcase named
|
||||
cpp11_template_double_brackets. R11245</P>
|
||||
<H2>Explicit conversion operators [done]</H2>
|
||||
<P>This is used when converting one type to another (eg. if
|
||||
(myObject) {}, where myObject is your custom class converted to
|
||||
bool).
|
||||
</P>
|
||||
<P>Requires both operator and function overloading which is not
|
||||
supported in any target language (eg. python, php).
|
||||
</P>
|
||||
<P>Done: Swig already supports the keyword "explicit" for
|
||||
function types as well. Added test case
|
||||
cpp11_explicit_conversion_operators. R11323</P>
|
||||
<H2>Template typedefs [partially done]</H2>
|
||||
<P>The new C++11 will allow creation of wrapper around the template.
|
||||
For example, if we want to do this:</P>
|
||||
<PRE>template< typename first, typename second, int third>
|
||||
class SomeType;
|
||||
|
||||
template< typename second>
|
||||
typedef SomeType<OtherType, second, 5> TypedefName; //Illegal in C++</PRE><P>
|
||||
This is still illegal! But we can now use the new syntax for
|
||||
achieving the same effect:</P>
|
||||
<PRE>template< typename first, typename second, int third>
|
||||
class SomeType;
|
||||
|
||||
template< typename second>
|
||||
using TypedefName = SomeType<OtherType, second, 5>;</PRE><P>
|
||||
Here we created a new wrapper TypedefName taking one template
|
||||
argument <second> which creates a type SomeType<OtherType,
|
||||
second, 5>. OtherType and 5 are predefined here and hidden from
|
||||
the user – the user only uses TypedefName type.</P>
|
||||
<P>The same goes for the following example:</P>
|
||||
<PRE>typedef void (*PFD)(double); // Old style
|
||||
using PF = void (*)(double); // New introduced syntax</PRE><P>
|
||||
Swig supports parsing typedefs for templates as well for example:</P>
|
||||
<PRE STYLE="margin-bottom: 0.5cm">typedef List<int> intList;</PRE><P>
|
||||
Done: Expanded support for the new 'using' syntax and template
|
||||
aliasing. Added testcase cpp11_template_typedefs. R11533</P>
|
||||
<P>TODO: Make Swig aware of the newly defined typedef. The TYPEDEF
|
||||
keyword is part of the storage_class rule and type+declarator (see
|
||||
c_decl rule) is the right part of the definition – for example void
|
||||
(*PFD)(double) cannot be transformed to void *(double) easily. To
|
||||
fully support the new 'using' form, we'll probably have to change the
|
||||
type, type_right rules and declarator, direct_declarator,
|
||||
notso_direct_declarator etc., which is PITA.</P>
|
||||
<H2>Unrestricted unions [done]</H2>
|
||||
<P>C++ currently offers usage of unions for types with trivial
|
||||
constructors only. The new C++11 standard allows usage of types with
|
||||
non-trivial constructors as well:</P>
|
||||
<PRE> struct point {
|
||||
point() {}
|
||||
point(int x, int y): x_(x), y_(y) {}
|
||||
int x_, y_;
|
||||
};
|
||||
union P {
|
||||
int z;
|
||||
double w;
|
||||
point p; // Illegal in C++; point has a non-trivial constructor. However, this is legal in C++11.
|
||||
} p1;</PRE><P>
|
||||
Swig already parses the given syntax.</P>
|
||||
<P>Done: Added testcase cpp11_unrestricted_unions. R11435, R11447</P>
|
||||
<P>Problem: GCC doesn't support unrestricted unions yet so there is
|
||||
no way to actually test, if it works.</P>
|
||||
<H2>Variadic templates [partially done]</H2>
|
||||
<P>The new C++11 offers the following syntax:</P>
|
||||
<PRE STYLE="margin-bottom: 0.5cm">template<typename... Values> class tuple;</PRE><P>
|
||||
This can be used for example:</P>
|
||||
<PRE STYLE="margin-bottom: 0.5cm">class tuple<int, std::vector<int>, std::map<std::string, std::vector<int>>> someInstanceName;</PRE><P>
|
||||
The ... is used in two cases. One is in the template header where it
|
||||
marks on the left the keywords 'typename' or 'class' and a type name
|
||||
on the right. The second case is usually in the function block to
|
||||
decompose typename on the left of the ... . For example:</P>
|
||||
<PRE>void printf(const char *s) {
|
||||
while (*s) {
|
||||
if (*s == '%' && *(++s) != '%')
|
||||
throw std::runtime_error("invalid format string: missing arguments");
|
||||
std::cout << *s++;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T, typename... Args>
|
||||
void printf(const char* s, T value, Args... args) { // recursive action – split previous args to value + args
|
||||
while (*s) {
|
||||
if (*s == '%' && *(++s) != '%') {
|
||||
std::cout << value;
|
||||
printf(*s ? ++s : s, args...); // call even when *s == 0 to detect extra arguments
|
||||
return;
|
||||
}
|
||||
std::cout << *s++;
|
||||
}
|
||||
throw std::logic_error("extra arguments provided to printf");
|
||||
}</PRE><P>
|
||||
The tricky part is that variadic templates can unpack actually
|
||||
anywhere – including the class inheritance :(</P>
|
||||
<PRE>template <typename... BaseClasses> class ClassName : public BaseClasses... {
|
||||
public:
|
||||
|
||||
ClassName (BaseClasses&&... baseClasses) : BaseClasses(baseClasses)... {}
|
||||
}</PRE><P>
|
||||
A new extension to sizeof is also introduced with this feature. The
|
||||
... after sizeof returns number of arguments:</P>
|
||||
<PRE>template<typename ...Args> struct SomeStruct {
|
||||
static const int size = sizeof...(Args);
|
||||
}
|
||||
// SomeStruct<Type1, Type2>::size is 2 and SomeStruct<>::size is 0</PRE><P>
|
||||
Done: Added syntax support for 'typename' or 'class' + ... + id.
|
||||
Added testcase cpp11_variadic_templates. R11458</P>
|
||||
<P>Done: Added syntax support for BaseClass + ..., type + ... + id in
|
||||
parameters and baseclass + ... for intializers after constructor.
|
||||
Extended Swig syntax to support sizeof...(Args). R11467</P>
|
||||
<P>Done: Fixed %template to support variadic number of templates.</P>
|
||||
<P>TODO: Only (if present) first variadically defined argument is
|
||||
currently used in %template directive. The next ones are ignored.</P>
|
||||
<H2>New string literals [partially done]</H2>
|
||||
<P>Beside the implementation, the new C++11 Unicode and custom
|
||||
delimeter constants can occur in templates in the header file.
|
||||
</P>
|
||||
<P>Done: Added symbols 'u', 'u8' and 'U' to mark the beginning of the
|
||||
UTF string. Also added test case cpp11_raw_string_literals. R11327</P>
|
||||
<P>Done: Added R"DELIMITER[, ]DELIMITER" for a custom
|
||||
delimiter for the beginning/end of the string. R11328</P>
|
||||
<P>TODO: Fix the Swig's C++ preprocessor bug when parsing an odd
|
||||
number of “ inside the string brackets. See
|
||||
Source/Preprocessor/cpp.c.</P>
|
||||
<H2>User-defined literals [partially done]</H2>
|
||||
<P>C++ has different suffix literals. eg. 12.5f marks the number 12.5
|
||||
as float.
|
||||
</P>
|
||||
<P>C++11 allows user to define his own suffix for the strings always
|
||||
starting with the underscore (_). eg. int a = "hello"_mySuffix;
|
||||
</P>
|
||||
<P>The syntax is similar to other operator overloading functions:
|
||||
</P>
|
||||
<PRE STYLE="margin-bottom: 0.5cm"> OutputType operator "" _mySuffix(const char * string_values);</PRE><P>
|
||||
The null terminated const char* is the string between the "".
|
||||
The _mySuffix is the name of the suffix operator. And the OutputType
|
||||
is the outputType the operator returns.
|
||||
</P>
|
||||
<P>Other forms are:
|
||||
</P>
|
||||
<PRE> OutputType operator "" _mySuffix(const char * string_values, size_t num_chars);
|
||||
OutputType operator "" _mySuffix(const wchar_t * string_values, size_t num_chars);
|
||||
OutputType operator "" _mySuffix(const char16_t * string_values, size_t num_chars);
|
||||
OutputType operator "" _mySuffix(const char32_t * string_values, size_t num_chars);
|
||||
OutputType operator "" _mySuffix(int value); /* cooked version - ie. atoi() of string */</PRE><P>
|
||||
Another possibility is to use variadic templates:
|
||||
</P>
|
||||
<PRE> template<char...> OutputType operator "" _mySuffix();
|
||||
OutputType someVariable = "1234"_mySuffix;</PRE><P>
|
||||
This instantiates the literal processing function as
|
||||
operator""_Suffix<'1', '2', '3', '4'>. In this form,
|
||||
there is no terminating null character to the string. The main
|
||||
purpose to doing this is to use C++11's constexpr keyword and the
|
||||
compiler to allow the literal to be transformed entirely at compile
|
||||
time, assuming OutputType is a constexpr-constructable and copyable
|
||||
type, and the literal processing function is a constexpr function.</P>
|
||||
<P>Article:
|
||||
<A HREF="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2765.pdf">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2765.pdf</A></P>
|
||||
<P>Done: Added syntax support for userdefined literals. Added
|
||||
testcase cpp11_userdefined_literals.i. R11494</P>
|
||||
<P>TODO: %rename doesn't parse operator”” yet.</P>
|
||||
<H2>Thread-local storage [done]
|
||||
</H2>
|
||||
<P>New C++11 introduces keyword "thread_local" which marks
|
||||
the following variable dynamically located depending on the current
|
||||
thread when using the address-of (&) operator.
|
||||
</P>
|
||||
<P>Syntax:
|
||||
</P>
|
||||
<PRE> struct A {
|
||||
thread_local int val;
|
||||
};</PRE><P>
|
||||
Done: Add "thread_local" keyword to Swig. Added testcase
|
||||
cpp11_thread_local. R11393</P>
|
||||
<H2>Defaulting/deleting of standard functions on C++ objects [done]</H2>
|
||||
<P>C++ automatically creates default constructor with empty
|
||||
parameters, copy constructor, operator= and destructor for any class.
|
||||
Sometimes user wants to explicitly remove one of them or enable them
|
||||
(eg. default constructor with empty parameters doesn't work any more,
|
||||
if any other constructor is defined).
|
||||
</P>
|
||||
<P>Words "default" and "delete" are introduced.
|
||||
The syntax is similar to declaration of pure virtual function:
|
||||
</P>
|
||||
<PRE> struct NonCopyable {
|
||||
NonCopyable & operator=(const NonCopyable&) = delete; /* Removes operator= */
|
||||
NonCopyable(const NonCopyable&) = delete; /* Removed copy constructor */
|
||||
NonCopyable() = default; /* Explicitly allows the empty constructor */
|
||||
void *operator new(std::size_t) = delete; /* Removes new NonCopyable */
|
||||
};</PRE><P>
|
||||
User has the ability by using keyword delete to disallow calling of
|
||||
the standard functions brought by C++ itself.
|
||||
</P>
|
||||
<PRE> struct A1 {
|
||||
void f(int i);
|
||||
void f(double i) = delete; /* Don't cast double to int. Compiler returns an error */
|
||||
};
|
||||
struct A2 {
|
||||
void f(int i);
|
||||
template<class T> void f(T) = delete; /* Only accept int */
|
||||
};</PRE><P>
|
||||
Ignored: Swig already parses the keywords "= delete" and "=
|
||||
default". These keywords are used for built-in functions (copy
|
||||
constructor, operator= etc.), which are ignored by Swig anyway.</P>
|
||||
<P>Done: Added testcase cpp11_default_delete. R11535</P>
|
||||
<H2>Type long long int [done]</H2>
|
||||
<P>Type long long int is an integer type that has at least 64 useful
|
||||
bits. C99 added it to its standard, but the C++ didn't adopt it until
|
||||
C++11. Most C++ compilers supported it though.
|
||||
</P>
|
||||
<P>Done: Swig already parses the C code including the long long type.
|
||||
</P>
|
||||
<H2>Static assertions [done]</H2>
|
||||
<P>static_assert() can be used at class scope as well eg.:
|
||||
</P>
|
||||
<PRE> template <typename T>
|
||||
struct Check {
|
||||
static_assert(sizeof(int) <= sizeof(T), "not big enough");
|
||||
};</PRE><P>
|
||||
Done: Added syntax support for "static_assert()". Added
|
||||
test case cpp11_static_assert. R11369</P>
|
||||
<H2>Allow sizeof to work on members of classes without an explicit
|
||||
object [done]</H2>
|
||||
<P>C++11 allows calls of sizeof to concrete objects as well:
|
||||
</P>
|
||||
<PRE> struct A { int member; };
|
||||
sizeof(A::member); //Does not work with C++03. Okay with C++11</PRE><P>
|
||||
This kind of syntax is already supported by Swig.</P>
|
||||
<P>Done: Added testcase cpp11_sizeof_objects. R11538
|
||||
</P>
|
||||
<H2>Threading facilities [ignored]</H2>
|
||||
<P>C++11 will add the following classes to the standard library:
|
||||
</P>
|
||||
<PRE> * std::thread
|
||||
* std::mutex, std::recursive_mutex
|
||||
* std::condition_variable, std::condition_variable_any
|
||||
* std::lock_guard, std::unique_lock
|
||||
* std::packaged_task</PRE><P>
|
||||
Ignored: No changes to the language itself is made.
|
||||
</P>
|
||||
<H2>Tuple types [TODO]</H2>
|
||||
<P>Tuple is array of various types. C++11 introduced this feature
|
||||
using variadic templates. Tuple is defined as:</P>
|
||||
<PRE STYLE="margin-bottom: 0.5cm">template <class ...Types> class tuple;</PRE><P>
|
||||
Constructor is automatically generated filling the tuple elements.
|
||||
get<X> function is introduced to get the Xth element in the
|
||||
tuple.</P>
|
||||
<PRE>typedef tuple< int, double, long &, const char * > test_tuple ;
|
||||
long lengthy = 12 ;
|
||||
test_tuple proof( 18, 6.5, lengthy, "Ciao!" ) ;
|
||||
lengthy = get<0>(proof) ; // Assign to 'lengthy' the value 18.
|
||||
get<3>(proof) = " Beautiful!" ; // Modify the tuple’s fourth element.</PRE><P>
|
||||
Tuples can be copied to each other, if all the elements are copiable:</P>
|
||||
<PRE>typedef tuple< int , double, string > tuple_1 t1 ;
|
||||
typedef tuple< char, short , const char * > tuple_2 t2( 'X', 2, "Hola!" ) ;
|
||||
t1 = t2 ; // Ok, first two elements can be converted,
|
||||
// the third one can be constructed from a 'const char *'.</PRE><P>
|
||||
TODO: Implement wrappers for the tuplet<> class.</P>
|
||||
<H2>Hash tables [TODO]</H2>
|
||||
<P>C++11 introduces the "unordered" version of existing
|
||||
types, which in practice work faster than the linear types:
|
||||
</P>
|
||||
<PRE> - unordered set
|
||||
- unordered multiset
|
||||
- unordered map
|
||||
- unordered multimap</PRE><P>
|
||||
Swig should use the "unordered" types exactly the same as
|
||||
the original linear types.</P>
|
||||
<P>Problem: Unordered types do not contain exactly same members as
|
||||
ordered ones (eg. _Hashtable_iterator does not offer operator--() and
|
||||
constructor with compare function which is required). So simply
|
||||
aliasing unordered classes to ordered ones doesn't work.</P>
|
||||
<P>TODO: Implement wrappers for unordered_ types. Initial work is
|
||||
already done in Lib/std/unordered_*.i files.</P>
|
||||
<H2>Regular expressions [ignored]</H2>
|
||||
<P>Two new classes are introduced in C++11: basic_regex and
|
||||
match_results. Both are defined in regex header file.
|
||||
</P>
|
||||
<P>Ignored: The new feature extends the standardy library only. No
|
||||
changes to Swig needed.
|
||||
</P>
|
||||
<H2>General-purpose smart pointers [done]</H2>
|
||||
<P>This feature deprecates auto_ptr and adds shared_ptr, weak_ptr and
|
||||
unique_ptr to the standard library.
|
||||
</P>
|
||||
<P>This feature only adds the smart pointers to the standard library
|
||||
and doesn't effect the C++ syntax.</P>
|
||||
<P>Done: Added test case which uses all three smart pointers in the
|
||||
class. R11394</P>
|
||||
<P>Problem: GCC standard library doesn't contain the new smart
|
||||
pointers yet.
|
||||
</P>
|
||||
<H2>Extensible random number facility [ignored]</H2>
|
||||
<P>This feature standardize the pseudo random number algorithm
|
||||
(currently, the random number generator was dependent on the
|
||||
platform/compiler). It adds functions linear_congruential,
|
||||
subtract_with_carry and mersenne_twister and symbols
|
||||
uniform_int_distribution, bernoulli_distribution,
|
||||
geometric_distribution, poisson_distribution, binomial_distribution,
|
||||
uniform_real_distribution, exponential_distribution,
|
||||
normal_distribution and gamma_distribution to the standard library.
|
||||
</P>
|
||||
<P>Ignored: The new feature extends the standardy library only. No
|
||||
changes to Swig needed.
|
||||
</P>
|
||||
<H2>Wrapper reference [ignored]</H2>
|
||||
<P>This feature adds ref and cref classes to the standard library
|
||||
(#include <utility>) usually used in tempalte functions.
|
||||
</P>
|
||||
<P>Ignored: The new feature extends the standardy library only. No
|
||||
changes to Swig needed.
|
||||
</P>
|
||||
<H2>Polymorphous wrappers for function objects [done]</H2>
|
||||
<P>Two features are introduced:
|
||||
</P>
|
||||
<UL>
|
||||
<LI><P>The function template wrapper:
|
||||
</P>
|
||||
</UL>
|
||||
<PRE STYLE="margin-bottom: 0.5cm"> function<int ( int, int )> pF;</PRE>
|
||||
<UL>
|
||||
<LI><P>and the function object:
|
||||
</P>
|
||||
</UL>
|
||||
<PRE> struct Test {
|
||||
bool operator()( short x, short y );
|
||||
};</PRE><P>
|
||||
Swig already supports the two.</P>
|
||||
<P>Done: Added a runtime testcase for function objects
|
||||
cpp11_function_objects. R11419.</P>
|
||||
<H2>Type traits for metaprogramming [ignored]</H2>
|
||||
<P>C++11 adds a new header file <type_traits> which includes
|
||||
helper functions to determine the template type while initializing
|
||||
the object at compile time.
|
||||
</P>
|
||||
<P>Swig already supports the following code:
|
||||
</P>
|
||||
<PRE> template< int B, int N >
|
||||
struct Pow {
|
||||
// recursive call and recombination.
|
||||
enum{ value = B*Pow< B, N-1 >::value };
|
||||
};
|
||||
template< int B > struct Pow< B, 0 > // <EM>N == 0</EM> condition of termination.
|
||||
{
|
||||
enum{ value = 1 };
|
||||
};
|
||||
int quartic_of_three = Pow< 3, 4 >::value ;</PRE><P>
|
||||
Functions is_convertible, is_integral, is_integral_const etc. are
|
||||
part of the new header:
|
||||
</P>
|
||||
<PRE>// First way of operating.
|
||||
template< bool B > struct algorithm {
|
||||
template< class T1, class T2 > int do_it( T1 &, T2 & ) { /*...*/ }
|
||||
};
|
||||
// Second way of operating.
|
||||
template<> struct algorithm<true> {
|
||||
template< class T1, class T2 > int do_it( T1, T2 ) { /*...*/ }
|
||||
};
|
||||
// Instantiating 'elaborate' will automatically instantiate the correct way to operate.
|
||||
template< class T1, class T2 > int elaborate( T1 A, T2 B ) {
|
||||
// Use the second way only if 'T1' is an integer and if 'T2' is
|
||||
// in floating point, otherwise use the first way.
|
||||
return algorithm< is_integral<T1>::value && is_floating_point<T2>::value >::do_it( A, B );
|
||||
}</PRE><P>
|
||||
Swig correctly parses the syntax for template<bool>,
|
||||
template<class T> and template<>.
|
||||
</P>
|
||||
<P>Ignored: Swig requires explicitly defined template class
|
||||
(%template directive) to export it to the target language.</P>
|
||||
<H2>Uniform method for computing return type of function objects
|
||||
[partially done]</H2>
|
||||
<P>The template function is introduced: std::result_of() which
|
||||
depends on decltype:
|
||||
</P>
|
||||
<PRE>template< class Obj >
|
||||
class calculus_ver2 {
|
||||
public:
|
||||
template< class Arg >
|
||||
typename std::result_of<Obj(Arg)>::type operator()( Arg& a ) const {
|
||||
return member(a);
|
||||
}
|
||||
private:
|
||||
Obj member;
|
||||
};</PRE><P>
|
||||
Swig correctly parses the result_of class.</P>
|
||||
<P>TODO: The return type (the result_of::type member) is not
|
||||
calculated by Swig. This needs a much more complex semantic parser.</P>
|
||||
<P>Done: Added testcase cpp11_result_of. R11534</P>
|
||||
</BODY>
|
||||
</HTML>
|
||||
|
|
@ -280,39 +280,39 @@ actual function.
|
|||
|
||||
<div class="code">example_wrap.i
|
||||
<pre>
|
||||
... lots of SWIG internals ...
|
||||
... lots of SWIG internals ...
|
||||
|
||||
EXPORT int ACL___fact__SWIG_0 (char *larg1) {
|
||||
int lresult = (int)0 ;
|
||||
char *arg1 = (char *) 0 ;
|
||||
int result;
|
||||
|
||||
arg1 = larg1;
|
||||
try {
|
||||
result = (int)fact(arg1);
|
||||
|
||||
lresult = result;
|
||||
return lresult;
|
||||
} catch (...) {
|
||||
return (int)0;
|
||||
}
|
||||
int lresult = (int)0 ;
|
||||
char *arg1 = (char *) 0 ;
|
||||
int result;
|
||||
|
||||
arg1 = larg1;
|
||||
try {
|
||||
result = (int)fact(arg1);
|
||||
|
||||
lresult = result;
|
||||
return lresult;
|
||||
} catch (...) {
|
||||
return (int)0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
EXPORT int ACL___fact__SWIG_1 (int larg1) {
|
||||
int lresult = (int)0 ;
|
||||
int arg1 ;
|
||||
int result;
|
||||
|
||||
arg1 = larg1;
|
||||
try {
|
||||
result = (int)fact(arg1);
|
||||
|
||||
lresult = result;
|
||||
return lresult;
|
||||
} catch (...) {
|
||||
return (int)0;
|
||||
}
|
||||
int lresult = (int)0 ;
|
||||
int arg1 ;
|
||||
int result;
|
||||
|
||||
arg1 = larg1;
|
||||
try {
|
||||
result = (int)fact(arg1);
|
||||
|
||||
lresult = result;
|
||||
return lresult;
|
||||
} catch (...) {
|
||||
return (int)0;
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -324,7 +324,7 @@ what is generated when parsing C code:
|
|||
|
||||
<div class="targetlang">
|
||||
<pre>
|
||||
...
|
||||
...
|
||||
|
||||
(swig-in-package ())
|
||||
|
||||
|
|
@ -526,8 +526,8 @@ interested in generating an interface to C++.
|
|||
<pre>
|
||||
%module ffargs
|
||||
|
||||
%ffargs(strings_convert="nil",call_direct="t") foo;
|
||||
%ffargs(strings_convert="nil",release_heap=":never",optimize_for_space="t") bar;
|
||||
%ffargs(strings_convert="nil", call_direct="t") foo;
|
||||
%ffargs(strings_convert="nil", release_heap=":never", optimize_for_space="t") bar;
|
||||
|
||||
int foo(float f1, float f2);
|
||||
int foo(float f1, char c2);
|
||||
|
|
@ -688,10 +688,10 @@ char *xxx();
|
|||
%include "foo.h"
|
||||
|
||||
namespace car {
|
||||
...
|
||||
namespace tires {
|
||||
int do_something(int n);
|
||||
}
|
||||
...
|
||||
namespace tires {
|
||||
int do_something(int n);
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1209,8 +1209,8 @@ class schema.
|
|||
<div class="code">synonyms.h
|
||||
<pre>
|
||||
class A {
|
||||
int x;
|
||||
int y;
|
||||
int x;
|
||||
int y;
|
||||
};
|
||||
|
||||
typedef A Foo;
|
||||
|
|
@ -1336,70 +1336,70 @@ float xxx(A *inst, int x); /* return x + A->x + A->y */
|
|||
<div class="code">overload_wrap.cxx
|
||||
<pre>
|
||||
EXPORT void ACL___delete_A__SWIG_0 (A *larg1) {
|
||||
A *arg1 = (A *) 0 ;
|
||||
|
||||
arg1 = larg1;
|
||||
try {
|
||||
delete arg1;
|
||||
|
||||
} catch (...) {
|
||||
|
||||
}
|
||||
A *arg1 = (A *) 0 ;
|
||||
|
||||
arg1 = larg1;
|
||||
try {
|
||||
delete arg1;
|
||||
|
||||
} catch (...) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
EXPORT float ACL___xxx__SWIG_0 (int larg1, int larg2) {
|
||||
float lresult = (float)0 ;
|
||||
int arg1 ;
|
||||
int arg2 ;
|
||||
float result;
|
||||
|
||||
arg1 = larg1;
|
||||
arg2 = larg2;
|
||||
try {
|
||||
result = (float)xxx(arg1,arg2);
|
||||
|
||||
lresult = result;
|
||||
return lresult;
|
||||
} catch (...) {
|
||||
return (float)0;
|
||||
}
|
||||
float lresult = (float)0 ;
|
||||
int arg1 ;
|
||||
int arg2 ;
|
||||
float result;
|
||||
|
||||
arg1 = larg1;
|
||||
arg2 = larg2;
|
||||
try {
|
||||
result = (float)xxx(arg1, arg2);
|
||||
|
||||
lresult = result;
|
||||
return lresult;
|
||||
} catch (...) {
|
||||
return (float)0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
EXPORT float ACL___xxx__SWIG_1 (int larg1) {
|
||||
float lresult = (float)0 ;
|
||||
int arg1 ;
|
||||
float result;
|
||||
|
||||
arg1 = larg1;
|
||||
try {
|
||||
result = (float)xxx(arg1);
|
||||
|
||||
lresult = result;
|
||||
return lresult;
|
||||
} catch (...) {
|
||||
return (float)0;
|
||||
}
|
||||
float lresult = (float)0 ;
|
||||
int arg1 ;
|
||||
float result;
|
||||
|
||||
arg1 = larg1;
|
||||
try {
|
||||
result = (float)xxx(arg1);
|
||||
|
||||
lresult = result;
|
||||
return lresult;
|
||||
} catch (...) {
|
||||
return (float)0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
EXPORT float ACL___xxx__SWIG_2 (A *larg1, int larg2) {
|
||||
float lresult = (float)0 ;
|
||||
A *arg1 = (A *) 0 ;
|
||||
int arg2 ;
|
||||
float result;
|
||||
|
||||
arg1 = larg1;
|
||||
arg2 = larg2;
|
||||
try {
|
||||
result = (float)xxx(arg1,arg2);
|
||||
|
||||
lresult = result;
|
||||
return lresult;
|
||||
} catch (...) {
|
||||
return (float)0;
|
||||
}
|
||||
float lresult = (float)0 ;
|
||||
A *arg1 = (A *) 0 ;
|
||||
int arg2 ;
|
||||
float result;
|
||||
|
||||
arg1 = larg1;
|
||||
arg2 = larg2;
|
||||
try {
|
||||
result = (float)xxx(arg1, arg2);
|
||||
|
||||
lresult = result;
|
||||
return lresult;
|
||||
} catch (...) {
|
||||
return (float)0;
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1675,21 +1675,21 @@ opoverload>
|
|||
<pre>
|
||||
return-val wrapper-name(parm0, parm1, ..., parmN)
|
||||
{
|
||||
return-val lresult; /* return value from wrapper */
|
||||
<local-declaration>
|
||||
... results; /* return value from function call */
|
||||
return-val lresult; /* return value from wrapper */
|
||||
<local-declaration>
|
||||
... results; /* return value from function call */
|
||||
|
||||
<binding locals to parameters>
|
||||
<binding locals to parameters>
|
||||
|
||||
try {
|
||||
result = function-name(local0, local1, ..., localN);
|
||||
try {
|
||||
result = function-name(local0, local1, ..., localN);
|
||||
|
||||
<convert and bind result to lresult>
|
||||
<convert and bind result to lresult>
|
||||
|
||||
return lresult;
|
||||
catch (...) {
|
||||
return (int)0;
|
||||
}
|
||||
return lresult;
|
||||
catch (...) {
|
||||
return (int)0;
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -354,7 +354,7 @@ Modify the <tt>nativeCall</tt> method in <tt>src/org/swig/simple/SwigSimple.java
|
|||
|
||||
int x = 42;
|
||||
int y = 105;
|
||||
int g = example.gcd(x,y);
|
||||
int g = example.gcd(x, y);
|
||||
outputText.append("The greatest common divisor of " + x + " and " + y + " is " + g + "\n");
|
||||
|
||||
// Manipulate the Foo global variable
|
||||
|
|
@ -661,7 +661,7 @@ public class SwigClass extends Activity
|
|||
// ----- Call some methods -----
|
||||
|
||||
outputText.append( "\nHere are some properties of the shapes:\n" );
|
||||
Shape[] shapes = {c,s};
|
||||
Shape[] shapes = {c, s};
|
||||
for (int i=0; i<shapes.length; i++)
|
||||
{
|
||||
outputText.append( " " + shapes[i].toString() + "\n" );
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ like this (shown for Python):
|
|||
</p>
|
||||
|
||||
<div class="targetlang"><pre>
|
||||
>>> a = add(3,4)
|
||||
>>> a = add(3, 4)
|
||||
>>> print a
|
||||
7
|
||||
>>>
|
||||
|
|
@ -148,7 +148,7 @@ For example, consider this code:
|
|||
%include "typemaps.i"
|
||||
%apply int *OUTPUT { int *width, int *height };
|
||||
|
||||
// Returns a pair (width,height)
|
||||
// Returns a pair (width, height)
|
||||
void getwinsize(int winid, int *width, int *height);
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -158,7 +158,7 @@ In this case, the function returns multiple values, allowing it to be used like
|
|||
</p>
|
||||
|
||||
<div class="targetlang"><pre>
|
||||
>>> w,h = genwinsize(wid)
|
||||
>>> w, h = genwinsize(wid)
|
||||
>>> print w
|
||||
400
|
||||
>>> print h
|
||||
|
|
@ -245,7 +245,7 @@ When the function is used in the scripting language interpreter, it will work li
|
|||
</p>
|
||||
|
||||
<div class="targetlang"><pre>
|
||||
result = add(3,4)
|
||||
result = add(3, 4)
|
||||
</pre></div>
|
||||
|
||||
<H3><a name="Arguments_nn5">10.1.3 Output parameters</a></H3>
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
<li><a href="#CPlusPlus11_strongly_typed_enumerations">Strongly typed enumerations</a>
|
||||
<li><a href="#CPlusPlus11_double_angle_brackets">Double angle brackets</a>
|
||||
<li><a href="#CPlusPlus11_explicit_conversion_operators">Explicit conversion operators</a>
|
||||
<li><a href="#CPlusPlus11_alias_templates">Alias templates</a>
|
||||
<li><a href="#CPlusPlus11_alias_templates">Type alias and alias templates</a>
|
||||
<li><a href="#CPlusPlus11_unrestricted_unions">Unrestricted unions</a>
|
||||
<li><a href="#CPlusPlus11_variadic_templates">Variadic templates</a>
|
||||
<li><a href="#CPlusPlus11_new_string_literals">New string literals</a>
|
||||
|
|
@ -52,7 +52,7 @@
|
|||
<li><a href="#CPlusPlus11_general_purpose_smart_pointers">General-purpose smart pointers</a>
|
||||
<li><a href="#CPlusPlus11_extensible_random_number_facility">Extensible random number facility</a>
|
||||
<li><a href="#CPlusPlus11_wrapper_reference">Wrapper reference</a>
|
||||
<li><a href="#CPlusPlus11_polymorphous_wrappers_for_function_objects">Polymorphous wrappers for function objects</a>
|
||||
<li><a href="#CPlusPlus11_polymorphous_wrappers_for_function_objects">Polymorphic wrappers for function objects</a>
|
||||
<li><a href="#CPlusPlus11_type_traits_for_metaprogramming">Type traits for metaprogramming</a>
|
||||
<li><a href="#CPlusPlus11_uniform_method_for_computing_return_type_of_function_objects">Uniform method for computing return type of function objects</a>
|
||||
</ul>
|
||||
|
|
@ -203,7 +203,7 @@ public:
|
|||
<p>And then call this constructor from your target language, for example, in Python, the following will call the constructor taking the <tt>std::vector</tt>:</p>
|
||||
|
||||
<div class="targetlang"><pre>
|
||||
>>> c = Container( [1,2,3,4] )
|
||||
>>> c = Container( [1, 2, 3, 4] )
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
|
|
@ -392,7 +392,7 @@ auto SomeStruct::FuncName(int x, int y) -> int {
|
|||
|
||||
<div class="targetlang"><pre>
|
||||
>>> a = SomeStruct()
|
||||
>>> a.FuncName(10,5)
|
||||
>>> a.FuncName(10, 5)
|
||||
15
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -457,10 +457,10 @@ This kind of initialization is handled by SWIG.
|
|||
<div class="code"><pre>
|
||||
class SomeClass {
|
||||
public:
|
||||
SomeClass() {}
|
||||
explicit SomeClass(int new_value) : value(new_value) {}
|
||||
SomeClass() {}
|
||||
explicit SomeClass(int new_value) : value(new_value) {}
|
||||
|
||||
int value = 5;
|
||||
int value = 5;
|
||||
};
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -603,37 +603,11 @@ Conversion operators either with or without <tt>explicit</tt> need renaming to a
|
|||
them available as a normal proxy method.
|
||||
</p>
|
||||
|
||||
<H3><a name="CPlusPlus11_alias_templates">7.2.16 Alias templates</a></H3>
|
||||
<H3><a name="CPlusPlus11_alias_templates">7.2.16 Type alias and alias templates</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
The following is an example of an alias template:
|
||||
|
||||
<div class="code"><pre>
|
||||
template< typename T1, typename T2, int >
|
||||
class SomeType {
|
||||
public:
|
||||
T1 a;
|
||||
T2 b;
|
||||
int c;
|
||||
};
|
||||
|
||||
template< typename T2 >
|
||||
using TypedefName = SomeType<char*, T2, 5>;
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
These are partially supported as SWIG will parse these and identify them, however, they are ignored as they are not added to the type system. A warning such as the following is issued:
|
||||
</p>
|
||||
|
||||
<div class="shell">
|
||||
<pre>
|
||||
example.i:13: Warning 342: The 'using' keyword in template aliasing is not fully supported yet.
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Similarly for non-template type aliasing:
|
||||
A type alias is a statement of the form:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
|
|
@ -641,22 +615,43 @@ using PFD = void (*)(double); // New introduced syntax
|
|||
</pre></div>
|
||||
|
||||
<p>
|
||||
A warning will be issued:
|
||||
which is equivalent to the old style typedef:
|
||||
</p>
|
||||
|
||||
<div class="shell">
|
||||
<pre>
|
||||
example.i:17: Warning 341: The 'using' keyword in type aliasing is not fully supported yet.
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
||||
<p>The equivalent old style typedefs can be used as a workaround:</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
typedef void (*PFD)(double); // The old style
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
The following is an example of an alias template:
|
||||
|
||||
<div class="code"><pre>
|
||||
template< typename T1, typename T2, int N >
|
||||
class SomeType {
|
||||
public:
|
||||
T1 a;
|
||||
T2 b;
|
||||
};
|
||||
|
||||
template< typename T2 >
|
||||
using TypedefName = SomeType<char*, T2, 5>;
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
SWIG supports both type aliasing and alias templates.
|
||||
However, in order to use an alias template, two <tt>%template</tt> directives must be used:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
%template(SomeTypeBool) SomeType<char*, bool, 5>;
|
||||
%template() TypedefName<bool>;
|
||||
</pre></div>
|
||||
|
||||
<p>Firstly, the actual template is instantiated with a name to be used by the target language, as per any template being wrapped.
|
||||
Secondly, the empty template instantiation, <tt>%template()</tt>, is required for the alias template.
|
||||
This second requirement is necessary to add the appropriate instantiated template type into the type system as SWIG does not automatically instantiate templates.
|
||||
See the <a href="SWIGPlus.html#SWIGPlus_nn30">Templates</a> section for more general information on wrapping templates.
|
||||
|
||||
<H3><a name="CPlusPlus11_unrestricted_unions">7.2.17 Unrestricted unions</a></H3>
|
||||
|
||||
|
||||
|
|
@ -693,7 +688,7 @@ initializers) with some limitations. The following code is correctly parsed:</p>
|
|||
<div class="code"><pre>
|
||||
template <typename... BaseClasses> class ClassName : public BaseClasses... {
|
||||
public:
|
||||
ClassName (BaseClasses &&... baseClasses) : BaseClasses(baseClasses)... {}
|
||||
ClassName (BaseClasses &&... baseClasses) : BaseClasses(baseClasses)... {}
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -823,7 +818,7 @@ reachable by the current thread can be defined as:</p>
|
|||
|
||||
<div class="code"><pre>
|
||||
struct A {
|
||||
static thread_local int val;
|
||||
static thread_local int val;
|
||||
};
|
||||
thread_local int global_val;
|
||||
</pre></div>
|
||||
|
|
@ -863,8 +858,8 @@ For example, the C++ compiler will not compile any code which attempts to use an
|
|||
|
||||
<div class="code"><pre>
|
||||
struct NoInt {
|
||||
void f(double i);
|
||||
void f(int) = delete;
|
||||
void f(double i);
|
||||
void f(int) = delete;
|
||||
};
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -999,7 +994,8 @@ Variadic template support requires further work to provide substantial tuple wra
|
|||
|
||||
<p>
|
||||
The new hash tables in the STL are <tt>unordered_set</tt>, <tt>unordered_multiset</tt>, <tt>unordered_map</tt>, <tt>unordered_multimap</tt>.
|
||||
These are not available in SWIG, but in principle should be easily implemented by adapting the current STL containers.
|
||||
These are not available in all target languages.
|
||||
Any missing support can in principle be easily implemented by adapting the current STL containers.
|
||||
</p>
|
||||
|
||||
<H3><a name="CPlusPlus11_regular_expressions">7.3.4 Regular expressions</a></H3>
|
||||
|
|
@ -1034,7 +1030,7 @@ Users would need to write their own typemaps if wrapper references are being use
|
|||
</p>
|
||||
|
||||
|
||||
<H3><a name="CPlusPlus11_polymorphous_wrappers_for_function_objects">7.3.8 Polymorphous wrappers for function objects</a></H3>
|
||||
<H3><a name="CPlusPlus11_polymorphous_wrappers_for_function_objects">7.3.8 Polymorphic wrappers for function objects</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -1062,7 +1058,7 @@ It does not involve <tt>std::function</tt>.
|
|||
|
||||
<div class="targetlang"><pre>
|
||||
t = Test()
|
||||
b = t(1,2) # invoke C++ function object
|
||||
b = t(1, 2) # invoke C++ function object
|
||||
</pre></div>
|
||||
|
||||
<H3><a name="CPlusPlus11_type_traits_for_metaprogramming">7.3.9 Type traits for metaprogramming</a></H3>
|
||||
|
|
|
|||
|
|
@ -544,12 +544,16 @@ unless the imclassname attribute is specified in the <a href="CSharp.html#CSharp
|
|||
|
||||
<p>
|
||||
The directory <tt>Examples/csharp</tt> has a number of simple examples.
|
||||
Visual Studio .NET 2003 solution and project files are available for compiling with the Microsoft .NET C# compiler on Windows.
|
||||
If your SWIG installation went well on a Unix environment and your C# compiler was detected, you should be able to type <tt>make</tt> in each example directory,
|
||||
then <tt>ilrun runme.exe</tt> (Portable.NET C# compiler) or <tt>mono runme.exe</tt> (Mono C# compiler) to run the examples.
|
||||
Visual Studio .NET 2003 solution and project files are available for compiling with the Microsoft .NET C#
|
||||
compiler on Windows. This also works with newer versions of Visual Studio if you allow
|
||||
it to convert the solution to the latest version.
|
||||
If your SWIG installation went well on a Unix environment and your C# compiler was detected, you should be able to type <tt>make</tt> in each example directory.
|
||||
After SWIG has run and both the C# and C/C++ compilers have finished building,
|
||||
the examples will be run, by either running <tt>runme.exe</tt> or by running
|
||||
<tt>mono runme.exe</tt> (Mono C# compiler).
|
||||
Windows users can also get the examples working using a
|
||||
<a href="http://www.cygwin.com">Cygwin</a> or <a href="http://www.mingw.org">MinGW</a> environment for automatic configuration of the example makefiles.
|
||||
Any one of the three C# compilers (Portable.NET, Mono or Microsoft) can be detected from within a Cygwin or Mingw environment if installed in your path.
|
||||
Any one of the C# compilers (Mono or Microsoft) can be detected from within a Cygwin or Mingw environment if installed in your path.
|
||||
|
||||
<H2><a name="CSharp_void_pointers">20.3 Void pointers</a></H2>
|
||||
|
||||
|
|
@ -598,7 +602,7 @@ For the <tt>%array_functions</tt> example, the equivalent usage would be:
|
|||
<pre>
|
||||
SWIGTYPE_p_double a = example.new_doubleArray(10); // Create an array
|
||||
for (int i=0; i<10; i++)
|
||||
example.doubleArray_setitem(a,i,2*i); // Set a value
|
||||
example.doubleArray_setitem(a, i, 2*i); // Set a value
|
||||
example.print_array(a); // Pass to C
|
||||
example.delete_doubleArray(a); // Destroy array
|
||||
</pre>
|
||||
|
|
@ -1021,18 +1025,18 @@ Now let's analyse the generated code to gain a fuller understanding of the typem
|
|||
<div class="code">
|
||||
<pre>
|
||||
SWIGEXPORT void SWIGSTDCALL CSharp_positivesonly(int jarg1) {
|
||||
int arg1 ;
|
||||
|
||||
arg1 = (int)jarg1;
|
||||
|
||||
if (arg1 < 0) {
|
||||
SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentOutOfRangeException,
|
||||
"only positive numbers accepted", "number");
|
||||
return ;
|
||||
}
|
||||
|
||||
positivesonly(arg1);
|
||||
|
||||
int arg1 ;
|
||||
|
||||
arg1 = (int)jarg1;
|
||||
|
||||
if (arg1 < 0) {
|
||||
SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentOutOfRangeException,
|
||||
"only positive numbers accepted", "number");
|
||||
return ;
|
||||
}
|
||||
|
||||
positivesonly(arg1);
|
||||
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1155,18 +1159,17 @@ The generated unmanaged code this time catches the C++ exception and converts it
|
|||
<div class="code">
|
||||
<pre>
|
||||
SWIGEXPORT void SWIGSTDCALL CSharp_negativesonly(int jarg1) {
|
||||
int arg1 ;
|
||||
|
||||
arg1 = (int)jarg1;
|
||||
|
||||
try {
|
||||
negativesonly(arg1);
|
||||
|
||||
} catch (std::out_of_range e) {
|
||||
SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, e.what());
|
||||
return ;
|
||||
}
|
||||
|
||||
int arg1 ;
|
||||
|
||||
arg1 = (int)jarg1;
|
||||
|
||||
try {
|
||||
negativesonly(arg1);
|
||||
|
||||
} catch (std::out_of_range e) {
|
||||
SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, e.what());
|
||||
return ;
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1221,19 +1224,18 @@ SWIG generates a try catch block with the throws typemap code in the catch handl
|
|||
<div class="code">
|
||||
<pre>
|
||||
SWIGEXPORT void SWIGSTDCALL CSharp_evensonly(int jarg1) {
|
||||
int arg1 ;
|
||||
|
||||
arg1 = (int)jarg1;
|
||||
try {
|
||||
evensonly(arg1);
|
||||
int arg1 ;
|
||||
|
||||
arg1 = (int)jarg1;
|
||||
try {
|
||||
evensonly(arg1);
|
||||
}
|
||||
catch(std::out_of_range &_e) {
|
||||
{
|
||||
SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentException, (&_e)->what(), NULL);
|
||||
return ;
|
||||
}
|
||||
catch(std::out_of_range &_e) {
|
||||
{
|
||||
SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentException, (&_e)->what(), NULL);
|
||||
return ;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1592,8 +1594,8 @@ public class Base : global::System.IDisposable {
|
|||
BaseBoolMethod(new Base(b, false), flag);
|
||||
}
|
||||
|
||||
internal delegate uint SwigDelegateBase_0(uint x);
|
||||
internal delegate void SwigDelegateBase_1(global::System.IntPtr b, bool flag);
|
||||
public delegate uint SwigDelegateBase_0(uint x);
|
||||
public delegate void SwigDelegateBase_1(global::System.IntPtr b, bool flag);
|
||||
|
||||
private SwigDelegateBase_0 swigDelegate0;
|
||||
private SwigDelegateBase_1 swigDelegate1;
|
||||
|
|
@ -1643,20 +1645,20 @@ SWIGEXPORT void SWIGSTDCALL CSharp_Base_director_connect(void *objarg,
|
|||
|
||||
class SwigDirector_Base : public Base, public Swig::Director {
|
||||
public:
|
||||
SwigDirector_Base();
|
||||
virtual unsigned int UIntMethod(unsigned int x);
|
||||
virtual ~SwigDirector_Base();
|
||||
virtual void BaseBoolMethod(Base const &b, bool flag);
|
||||
SwigDirector_Base();
|
||||
virtual unsigned int UIntMethod(unsigned int x);
|
||||
virtual ~SwigDirector_Base();
|
||||
virtual void BaseBoolMethod(Base const &b, bool flag);
|
||||
|
||||
typedef unsigned int (SWIGSTDCALL* SWIG_Callback0_t)(unsigned int);
|
||||
typedef void (SWIGSTDCALL* SWIG_Callback1_t)(void *, unsigned int);
|
||||
void swig_connect_director(SWIG_Callback0_t callbackUIntMethod,
|
||||
SWIG_Callback1_t callbackBaseBoolMethod);
|
||||
typedef unsigned int (SWIGSTDCALL* SWIG_Callback0_t)(unsigned int);
|
||||
typedef void (SWIGSTDCALL* SWIG_Callback1_t)(void *, unsigned int);
|
||||
void swig_connect_director(SWIG_Callback0_t callbackUIntMethod,
|
||||
SWIG_Callback1_t callbackBaseBoolMethod);
|
||||
|
||||
private:
|
||||
SWIG_Callback0_t swig_callbackUIntMethod;
|
||||
SWIG_Callback1_t swig_callbackBaseBoolMethod;
|
||||
void swig_init_callbacks();
|
||||
SWIG_Callback0_t swig_callbackUIntMethod;
|
||||
SWIG_Callback1_t swig_callbackBaseBoolMethod;
|
||||
void swig_init_callbacks();
|
||||
};
|
||||
|
||||
void SwigDirector_Base::swig_connect_director(SWIG_Callback0_t callbackUIntMethod,
|
||||
|
|
@ -1682,7 +1684,7 @@ void SwigDirector_Base::BaseBoolMethod(Base const &b, bool flag) {
|
|||
unsigned int jflag ;
|
||||
|
||||
if (!swig_callbackBaseBoolMethod) {
|
||||
Base::BaseBoolMethod(b,flag);
|
||||
Base::BaseBoolMethod(b, flag);
|
||||
return;
|
||||
} else {
|
||||
jb = (Base *) &b;
|
||||
|
|
@ -1693,6 +1695,31 @@ void SwigDirector_Base::BaseBoolMethod(Base const &b, bool flag) {
|
|||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
The delegates from the above example are <tt>public</tt> by default:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
public delegate uint SwigDelegateBase_0(uint x);
|
||||
public delegate void SwigDelegateBase_1(global::System.IntPtr b, bool flag);
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
These can be changed if desired via the <tt>csdirectordelegatemodifiers</tt>
|
||||
<a href="Customization.html#Customization_features">%feature directive</a>.
|
||||
For example, using <tt>%feature("csdirectordelegatemodifiers") "internal"</tt>
|
||||
before SWIG parses the Base class will change all the delegates to <tt>internal</tt>:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
internal delegate uint SwigDelegateBase_0(uint x);
|
||||
internal delegate void SwigDelegateBase_1(global::System.IntPtr b, bool flag);
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<H3><a name="CSharp_director_caveats">20.6.3 Director caveats</a></H3>
|
||||
|
||||
|
||||
|
|
@ -1940,10 +1967,10 @@ and usage from C++
|
|||
|
||||
<div class="code">
|
||||
<pre>
|
||||
Container container;
|
||||
Element element(20);
|
||||
container.setElement(&element);
|
||||
cout << "element.value: " << container.getElement()->value << endl;
|
||||
Container container;
|
||||
Element element(20);
|
||||
container.setElement(&element);
|
||||
cout << "element.value: " << container.getElement()->value << endl;
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -2134,7 +2161,7 @@ The typemaps to achieve this are shown below.
|
|||
%typemap(csin,
|
||||
pre=" CDate temp$csinput = new CDate();",
|
||||
post=" $csinput = new System.DateTime(temp$csinput.getYear(),"
|
||||
" temp$csinput.getMonth(), temp$csinput.getDay(), 0, 0, 0);",
|
||||
" temp$csinput.getMonth(), temp$csinput.getDay(), 0, 0, 0);",
|
||||
cshin="out $csinput"
|
||||
) CDate &
|
||||
"$csclassname.getCPtr(temp$csinput)"
|
||||
|
|
@ -2240,7 +2267,7 @@ will be possible with the following <tt>CDate *</tt> typemaps
|
|||
%typemap(csin,
|
||||
pre=" CDate temp$csinput = new CDate($csinput.Year, $csinput.Month, $csinput.Day);",
|
||||
post=" $csinput = new System.DateTime(temp$csinput.getYear(),"
|
||||
" temp$csinput.getMonth(), temp$csinput.getDay(), 0, 0, 0);",
|
||||
" temp$csinput.getMonth(), temp$csinput.getDay(), 0, 0, 0);",
|
||||
cshin="ref $csinput"
|
||||
) CDate *
|
||||
"$csclassname.getCPtr(temp$csinput)"
|
||||
|
|
@ -2279,7 +2306,7 @@ The <tt>subtractYears</tt> method is nearly identical to the above <tt>addYears<
|
|||
%typemap(csin,
|
||||
pre=" using (CDate temp$csinput = new CDate($csinput.Year, $csinput.Month, $csinput.Day)) {",
|
||||
post=" $csinput = new System.DateTime(temp$csinput.getYear(),"
|
||||
" temp$csinput.getMonth(), temp$csinput.getDay(), 0, 0, 0);",
|
||||
" temp$csinput.getMonth(), temp$csinput.getDay(), 0, 0, 0);",
|
||||
terminator=" } // terminate temp$csinput using block",
|
||||
cshin="ref $csinput"
|
||||
) CDate *
|
||||
|
|
@ -2351,7 +2378,7 @@ The typemap type required is thus <tt>CDate *</tt>. Given that the previous sect
|
|||
%typemap(csin,
|
||||
pre=" CDate temp$csinput = new CDate($csinput.Year, $csinput.Month, $csinput.Day);",
|
||||
post=" $csinput = new System.DateTime(temp$csinput.getYear(),"
|
||||
" temp$csinput.getMonth(), temp$csinput.getDay(), 0, 0, 0);",
|
||||
" temp$csinput.getMonth(), temp$csinput.getDay(), 0, 0, 0);",
|
||||
cshin="ref $csinput"
|
||||
) CDate *
|
||||
"$csclassname.getCPtr(temp$csinput)"
|
||||
|
|
|
|||
|
|
@ -295,9 +295,9 @@
|
|||
|
||||
<p>
|
||||
The author of TinyCLOS, Gregor Kiczales, describes TinyCLOS as:
|
||||
"Tiny CLOS is a Scheme implementation of a `kernelized' CLOS, with a
|
||||
"Tiny CLOS is a Scheme implementation of a 'kernelized' CLOS, with a
|
||||
metaobject protocol. The implementation is even simpler than
|
||||
the simple CLOS found in `The Art of the Metaobject Protocol,'
|
||||
the simple CLOS found in 'The Art of the Metaobject Protocol',
|
||||
weighing in at around 850 lines of code, including (some)
|
||||
comments and documentation."
|
||||
</p>
|
||||
|
|
|
|||
|
|
@ -287,7 +287,7 @@
|
|||
<li><a href="CPlusPlus11.html#CPlusPlus11_strongly_typed_enumerations">Strongly typed enumerations</a>
|
||||
<li><a href="CPlusPlus11.html#CPlusPlus11_double_angle_brackets">Double angle brackets</a>
|
||||
<li><a href="CPlusPlus11.html#CPlusPlus11_explicit_conversion_operators">Explicit conversion operators</a>
|
||||
<li><a href="CPlusPlus11.html#CPlusPlus11_alias_templates">Alias templates</a>
|
||||
<li><a href="CPlusPlus11.html#CPlusPlus11_alias_templates">Type alias and alias templates</a>
|
||||
<li><a href="CPlusPlus11.html#CPlusPlus11_unrestricted_unions">Unrestricted unions</a>
|
||||
<li><a href="CPlusPlus11.html#CPlusPlus11_variadic_templates">Variadic templates</a>
|
||||
<li><a href="CPlusPlus11.html#CPlusPlus11_new_string_literals">New string literals</a>
|
||||
|
|
@ -310,7 +310,7 @@
|
|||
<li><a href="CPlusPlus11.html#CPlusPlus11_general_purpose_smart_pointers">General-purpose smart pointers</a>
|
||||
<li><a href="CPlusPlus11.html#CPlusPlus11_extensible_random_number_facility">Extensible random number facility</a>
|
||||
<li><a href="CPlusPlus11.html#CPlusPlus11_wrapper_reference">Wrapper reference</a>
|
||||
<li><a href="CPlusPlus11.html#CPlusPlus11_polymorphous_wrappers_for_function_objects">Polymorphous wrappers for function objects</a>
|
||||
<li><a href="CPlusPlus11.html#CPlusPlus11_polymorphous_wrappers_for_function_objects">Polymorphic wrappers for function objects</a>
|
||||
<li><a href="CPlusPlus11.html#CPlusPlus11_type_traits_for_metaprogramming">Type traits for metaprogramming</a>
|
||||
<li><a href="CPlusPlus11.html#CPlusPlus11_uniform_method_for_computing_return_type_of_function_objects">Uniform method for computing return type of function objects</a>
|
||||
</ul>
|
||||
|
|
@ -457,6 +457,7 @@
|
|||
<li><a href="Typemaps.html#Typemaps_nn32">"argout" typemap</a>
|
||||
<li><a href="Typemaps.html#Typemaps_nn33">"freearg" typemap</a>
|
||||
<li><a href="Typemaps.html#Typemaps_nn34">"newfree" typemap</a>
|
||||
<li><a href="Typemaps.html#Typemaps_ret">"ret" typemap</a>
|
||||
<li><a href="Typemaps.html#Typemaps_nn35">"memberin" typemap</a>
|
||||
<li><a href="Typemaps.html#Typemaps_nn36">"varin" typemap</a>
|
||||
<li><a href="Typemaps.html#Typemaps_nn37">"varout" typemap</a>
|
||||
|
|
@ -907,13 +908,14 @@
|
|||
<li><a href="Guile.html#Guile_nn14">Smobs</a>
|
||||
<li><a href="Guile.html#Guile_nn15">Garbage Collection</a>
|
||||
</ul>
|
||||
<li><a href="Guile.html#Guile_nn16">Exception Handling</a>
|
||||
<li><a href="Guile.html#Guile_nn17">Procedure documentation</a>
|
||||
<li><a href="Guile.html#Guile_nn18">Procedures with setters</a>
|
||||
<li><a href="Guile.html#Guile_nn19">GOOPS Proxy Classes</a>
|
||||
<li><a href="Guile.html#Guile_nn16">Native Guile pointers</a>
|
||||
<li><a href="Guile.html#Guile_nn17">Exception Handling</a>
|
||||
<li><a href="Guile.html#Guile_nn18">Procedure documentation</a>
|
||||
<li><a href="Guile.html#Guile_nn19">Procedures with setters</a>
|
||||
<li><a href="Guile.html#Guile_nn20">GOOPS Proxy Classes</a>
|
||||
<ul>
|
||||
<li><a href="Guile.html#Guile_nn20">Naming Issues</a>
|
||||
<li><a href="Guile.html#Guile_nn21">Linking</a>
|
||||
<li><a href="Guile.html#Guile_nn21">Naming Issues</a>
|
||||
<li><a href="Guile.html#Guile_nn22">Linking</a>
|
||||
</ul>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
@ -1014,6 +1016,7 @@
|
|||
<ul>
|
||||
<li><a href="Java.html#Java_helper_functions">C/C++ helper functions</a>
|
||||
<li><a href="Java.html#Java_class_extension">Class extension with %extend</a>
|
||||
<li><a href="Java.html#Java_proxycode">Class extension with %proxycode</a>
|
||||
<li><a href="Java.html#Java_exception_handling">Exception handling with %exception and %javaexception</a>
|
||||
<li><a href="Java.html#Java_method_access">Method access with %javamethodmodifiers</a>
|
||||
</ul>
|
||||
|
|
@ -1529,7 +1532,7 @@
|
|||
<li><a href="Python.html#Python_builtin_types">Built-in Types</a>
|
||||
<ul>
|
||||
<li><a href="Python.html#Python_builtin_limitations">Limitations</a>
|
||||
<li><a href="Python.html#Python_builtin_overloads">Operator overloads -- use them!</a>
|
||||
<li><a href="Python.html#Python_builtin_overloads">Operator overloads and slots -- use them!</a>
|
||||
</ul>
|
||||
<li><a href="Python.html#Python_nn30">Memory management</a>
|
||||
<li><a href="Python.html#Python_nn31">Python 2.2 and classic classes</a>
|
||||
|
|
@ -1595,6 +1598,13 @@
|
|||
<li><a href="Python.html#Python_absimport">Enforcing absolute import semantics</a>
|
||||
<li><a href="Python.html#Python_importfrominit">Importing from __init__.py</a>
|
||||
<li><a href="Python.html#Python_implicit_namespace_packages">Implicit Namespace Packages</a>
|
||||
<li><a href="Python.html#Python_package_search">Searching for the wrapper module</a>
|
||||
<ul>
|
||||
<li><a href="Python.html#Python_package_search_both_package_modules">Both modules in the same package</a>
|
||||
<li><a href="Python.html#Python_package_search_wrapper_split">Split modules</a>
|
||||
<li><a href="Python.html#Python_package_search_both_global_modules">Both modules are global</a>
|
||||
<li><a href="Python.html#Python_package_search_static">Statically linked C modules</a>
|
||||
</ul>
|
||||
</ul>
|
||||
<li><a href="Python.html#Python_python3support">Python 3 Support</a>
|
||||
<ul>
|
||||
|
|
@ -1604,6 +1614,11 @@
|
|||
<li><a href="Python.html#Python_nn77">Byte string output conversion</a>
|
||||
<li><a href="Python.html#Python_2_unicode">Python 2 Unicode</a>
|
||||
</ul>
|
||||
<li><a href="Python.html#Python_multithreaded">Support for Multithreaded Applications</a>
|
||||
<ul>
|
||||
<li><a href="Python.html#Python_thread_UI">UI for Enabling Multithreading Support</a>
|
||||
<li><a href="Python.html#Python_thread_performance">Multithread Performance</a>
|
||||
</ul>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- INDEX -->
|
||||
|
|
|
|||
|
|
@ -51,9 +51,9 @@ is a simple example:
|
|||
<pre>
|
||||
%contract sqrt(double x) {
|
||||
require:
|
||||
x >= 0;
|
||||
x >= 0;
|
||||
ensure:
|
||||
sqrt >= 0;
|
||||
sqrt >= 0;
|
||||
}
|
||||
|
||||
...
|
||||
|
|
@ -106,20 +106,20 @@ The <tt>%contract</tt> directive can also be applied to class methods and constr
|
|||
<pre>
|
||||
%contract Foo::bar(int x, int y) {
|
||||
require:
|
||||
x > 0;
|
||||
x > 0;
|
||||
ensure:
|
||||
bar > 0;
|
||||
bar > 0;
|
||||
}
|
||||
|
||||
%contract Foo::Foo(int a) {
|
||||
require:
|
||||
a > 0;
|
||||
a > 0;
|
||||
}
|
||||
|
||||
class Foo {
|
||||
public:
|
||||
Foo(int);
|
||||
int bar(int, int);
|
||||
Foo(int);
|
||||
int bar(int, int);
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -133,7 +133,7 @@ Thus, any contract that you specified for a base class will also be attached to
|
|||
<pre>
|
||||
class Spam : public Foo {
|
||||
public:
|
||||
int bar(int,int); // Gets contract defined for Foo::bar(int,int)
|
||||
int bar(int, int); // Gets contract defined for Foo::bar(int, int)
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -146,22 +146,22 @@ In addition to this, separate contracts can be applied to both the base class an
|
|||
<pre>
|
||||
%contract Foo::bar(int x, int) {
|
||||
require:
|
||||
x > 0;
|
||||
x > 0;
|
||||
}
|
||||
|
||||
%contract Spam::bar(int, int y) {
|
||||
require:
|
||||
y > 0;
|
||||
y > 0;
|
||||
}
|
||||
|
||||
class Foo {
|
||||
public:
|
||||
int bar(int,int); // Gets Foo::bar contract.
|
||||
int bar(int, int); // Gets Foo::bar contract.
|
||||
};
|
||||
|
||||
class Spam : public Foo {
|
||||
public:
|
||||
int bar(int,int); // Gets Foo::bar and Spam::bar contract
|
||||
int bar(int, int); // Gets Foo::bar and Spam::bar contract
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -225,7 +225,7 @@ function can be used in contracts. For example:
|
|||
|
||||
%contract move(SomeObject *, int direction, in) {
|
||||
require:
|
||||
check_direction(direction);
|
||||
check_direction(direction);
|
||||
}
|
||||
|
||||
#define UP 1
|
||||
|
|
@ -246,7 +246,7 @@ Alternatively, it can be used in typemaps and other directives. For example:
|
|||
%aggregate_check(int, check_direction, UP, DOWN, RIGHT, LEFT);
|
||||
|
||||
%typemap(check) int direction {
|
||||
if (!check_direction($1)) SWIG_exception(SWIG_ValueError, "Bad direction");
|
||||
if (!check_direction($1)) SWIG_exception(SWIG_ValueError, "Bad direction");
|
||||
}
|
||||
|
||||
#define UP 1
|
||||
|
|
|
|||
|
|
@ -56,12 +56,12 @@ handler. For example, you can specify the following:
|
|||
|
||||
<div class="code"><pre>
|
||||
%exception {
|
||||
try {
|
||||
$action
|
||||
}
|
||||
catch (RangeError) {
|
||||
... handle error ...
|
||||
}
|
||||
try {
|
||||
$action
|
||||
}
|
||||
catch (RangeError) {
|
||||
... handle error ...
|
||||
}
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -71,13 +71,13 @@ How the exception is handled depends on the target language, for example, Python
|
|||
|
||||
<div class="code"><pre>
|
||||
%exception {
|
||||
try {
|
||||
$action
|
||||
}
|
||||
catch (RangeError) {
|
||||
PyErr_SetString(PyExc_IndexError,"index out-of-bounds");
|
||||
SWIG_fail;
|
||||
}
|
||||
try {
|
||||
$action
|
||||
}
|
||||
catch (RangeError) {
|
||||
PyErr_SetString(PyExc_IndexError, "index out-of-bounds");
|
||||
SWIG_fail;
|
||||
}
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -116,7 +116,7 @@ static char error_message[256];
|
|||
static int error_status = 0;
|
||||
|
||||
void throw_exception(char *msg) {
|
||||
strncpy(error_message,msg,256);
|
||||
strncpy(error_message, msg, 256);
|
||||
error_status = 1;
|
||||
}
|
||||
|
||||
|
|
@ -193,7 +193,7 @@ extern int exception_status;
|
|||
|
||||
#define try if ((exception_status = setjmp(exception_buffer)) == 0)
|
||||
#define catch(val) else if (exception_status == val)
|
||||
#define throw(val) longjmp(exception_buffer,val)
|
||||
#define throw(val) longjmp(exception_buffer, val)
|
||||
#define finally else
|
||||
|
||||
/* Exception codes */
|
||||
|
|
@ -341,12 +341,12 @@ to specific declaration name. For example:
|
|||
<div class="code">
|
||||
<pre>
|
||||
%exception allocate {
|
||||
try {
|
||||
$action
|
||||
}
|
||||
catch (MemoryError) {
|
||||
croak("Out of memory");
|
||||
}
|
||||
try {
|
||||
$action
|
||||
}
|
||||
catch (MemoryError) {
|
||||
croak("Out of memory");
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -364,12 +364,12 @@ an exception handler for a specific class, you might write this:
|
|||
<div class="code">
|
||||
<pre>
|
||||
%exception Object::allocate {
|
||||
try {
|
||||
$action
|
||||
}
|
||||
catch (MemoryError) {
|
||||
croak("Out of memory");
|
||||
}
|
||||
try {
|
||||
$action
|
||||
}
|
||||
catch (MemoryError) {
|
||||
croak("Out of memory");
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -386,12 +386,12 @@ in the specified class as well as for identically named functions appearing in d
|
|||
<div class="code">
|
||||
<pre>
|
||||
%exception Object::allocate(int) {
|
||||
try {
|
||||
$action
|
||||
}
|
||||
catch (MemoryError) {
|
||||
croak("Out of memory");
|
||||
}
|
||||
try {
|
||||
$action
|
||||
}
|
||||
catch (MemoryError) {
|
||||
croak("Out of memory");
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -410,21 +410,21 @@ to attach exceptions to specific parts of a header file. For example:
|
|||
|
||||
// Define a few exception handlers for specific declarations
|
||||
%exception Object::allocate(int) {
|
||||
try {
|
||||
$action
|
||||
}
|
||||
catch (MemoryError) {
|
||||
croak("Out of memory");
|
||||
}
|
||||
try {
|
||||
$action
|
||||
}
|
||||
catch (MemoryError) {
|
||||
croak("Out of memory");
|
||||
}
|
||||
}
|
||||
|
||||
%exception Object::getitem {
|
||||
try {
|
||||
$action
|
||||
}
|
||||
catch (RangeError) {
|
||||
croak("Index out of range");
|
||||
}
|
||||
try {
|
||||
$action
|
||||
}
|
||||
catch (RangeError) {
|
||||
croak("Index out of range");
|
||||
}
|
||||
}
|
||||
...
|
||||
// Read a raw header file
|
||||
|
|
@ -560,17 +560,17 @@ common scripting language exceptions in a portable manner. For example :</p>
|
|||
%include exception.i
|
||||
|
||||
%exception {
|
||||
try {
|
||||
$action
|
||||
} catch(RangeError) {
|
||||
SWIG_exception(SWIG_ValueError, "Range Error");
|
||||
} catch(DivisionByZero) {
|
||||
SWIG_exception(SWIG_DivisionByZero, "Division by zero");
|
||||
} catch(OutOfMemory) {
|
||||
SWIG_exception(SWIG_MemoryError, "Out of memory");
|
||||
} catch(...) {
|
||||
SWIG_exception(SWIG_RuntimeError,"Unknown exception");
|
||||
}
|
||||
try {
|
||||
$action
|
||||
} catch(RangeError) {
|
||||
SWIG_exception(SWIG_ValueError, "Range Error");
|
||||
} catch(DivisionByZero) {
|
||||
SWIG_exception(SWIG_DivisionByZero, "Division by zero");
|
||||
} catch(OutOfMemory) {
|
||||
SWIG_exception(SWIG_MemoryError, "Out of memory");
|
||||
} catch(...) {
|
||||
SWIG_exception(SWIG_RuntimeError, "Unknown exception");
|
||||
}
|
||||
}
|
||||
|
||||
</pre></div>
|
||||
|
|
@ -611,8 +611,8 @@ example, consider a function like this:
|
|||
<div class="code">
|
||||
<pre>
|
||||
Foo *blah() {
|
||||
Foo *f = new Foo();
|
||||
return f;
|
||||
Foo *f = new Foo();
|
||||
return f;
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -645,7 +645,7 @@ you can attach it to class members and parameterized declarations as before. Fo
|
|||
<div class="code">
|
||||
<pre>
|
||||
%newobject ::blah(); // Only applies to global blah
|
||||
%newobject Object::blah(int,double); // Only blah(int,double) in Object
|
||||
%newobject Object::blah(int, double); // Only blah(int, double) in Object
|
||||
%newobject *::copy; // Copy method in all classes
|
||||
...
|
||||
</pre>
|
||||
|
|
@ -771,15 +771,15 @@ using the <tt>%feature</tt> directive. For example:
|
|||
<div class="code">
|
||||
<pre>
|
||||
%feature("except") Object::allocate {
|
||||
try {
|
||||
$action
|
||||
}
|
||||
catch (MemoryError) {
|
||||
croak("Out of memory");
|
||||
}
|
||||
try {
|
||||
$action
|
||||
}
|
||||
catch (MemoryError) {
|
||||
croak("Out of memory");
|
||||
}
|
||||
}
|
||||
|
||||
%feature("new","1") *::copy;
|
||||
%feature("new", "1") *::copy;
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -791,7 +791,7 @@ involving <tt>%feature</tt>:
|
|||
<div class="code">
|
||||
<pre>
|
||||
#define %exception %feature("except")
|
||||
#define %newobject %feature("new","1")
|
||||
#define %newobject %feature("new", "1")
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -811,10 +811,10 @@ are defined. For example:
|
|||
<pre>
|
||||
/* Define a global exception handler */
|
||||
%feature("except") {
|
||||
try {
|
||||
$action
|
||||
}
|
||||
...
|
||||
try {
|
||||
$action
|
||||
}
|
||||
...
|
||||
}
|
||||
|
||||
... bunch of declarations ...
|
||||
|
|
@ -831,7 +831,7 @@ The following are all equivalent:
|
|||
%feature("except") Object::method { $action };
|
||||
%feature("except") Object::method %{ $action %};
|
||||
%feature("except") Object::method " $action ";
|
||||
%feature("except","$action") Object::method;
|
||||
%feature("except", "$action") Object::method;
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -850,7 +850,7 @@ The following is the generic syntax for features:
|
|||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%feature("name","value", attribute1="AttributeValue1") symbol;
|
||||
%feature("name", "value", attribute1="AttributeValue1") symbol;
|
||||
%feature("name", attribute1="AttributeValue1") symbol {value};
|
||||
%feature("name", attribute1="AttributeValue1") symbol %{value%};
|
||||
%feature("name", attribute1="AttributeValue1") symbol "value";
|
||||
|
|
@ -867,11 +867,11 @@ In the following example, <tt>MyExceptionClass</tt> is the name of the Java clas
|
|||
<div class="code">
|
||||
<pre>
|
||||
%feature("except", throws="MyExceptionClass") Object::method {
|
||||
try {
|
||||
$action
|
||||
} catch (...) {
|
||||
... code to throw a MyExceptionClass Java exception ...
|
||||
}
|
||||
try {
|
||||
$action
|
||||
} catch (...) {
|
||||
... code to throw a MyExceptionClass Java exception ...
|
||||
}
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -914,13 +914,13 @@ int red; // mutable
|
|||
%feature("immutable"); // global enable
|
||||
int orange; // immutable
|
||||
|
||||
%feature("immutable","0"); // global disable
|
||||
%feature("immutable", "0"); // global disable
|
||||
int yellow; // mutable
|
||||
|
||||
%feature("immutable","1"); // another form of global enable
|
||||
%feature("immutable", "1"); // another form of global enable
|
||||
int green; // immutable
|
||||
|
||||
%feature("immutable",""); // clears the global feature
|
||||
%feature("immutable", ""); // clears the global feature
|
||||
int blue; // mutable
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -932,8 +932,8 @@ The above intersperses SWIG directives with C code. Of course you can target fea
|
|||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%feature("immutable","1") orange;
|
||||
%feature("immutable","1") green;
|
||||
%feature("immutable", "1") orange;
|
||||
%feature("immutable", "1") green;
|
||||
int red; // mutable
|
||||
int orange; // immutable
|
||||
int yellow; // mutable
|
||||
|
|
@ -949,10 +949,10 @@ The logic above can of course be inverted and rewritten as:
|
|||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%feature("immutable","1");
|
||||
%feature("immutable","0") red;
|
||||
%feature("immutable","0") yellow;
|
||||
%feature("immutable","0") blue;
|
||||
%feature("immutable", "1");
|
||||
%feature("immutable", "0") red;
|
||||
%feature("immutable", "0") yellow;
|
||||
%feature("immutable", "0") blue;
|
||||
int red; // mutable
|
||||
int orange; // immutable
|
||||
int yellow; // mutable
|
||||
|
|
@ -983,7 +983,7 @@ The concept of clearing features is discussed next.
|
|||
|
||||
<p>
|
||||
A feature stays in effect until it is explicitly cleared. A feature is cleared by
|
||||
supplying a <tt>%feature</tt> directive with no value. For example <tt>%feature("name","")</tt>.
|
||||
supplying a <tt>%feature</tt> directive with no value. For example <tt>%feature("name", "")</tt>.
|
||||
A cleared feature means that any feature exactly matching any previously defined feature is no longer used in the name matching rules.
|
||||
So if a feature is cleared, it might mean that another name matching rule will apply.
|
||||
To clarify, let's consider the <tt>except</tt> feature again (<tt>%exception</tt>):
|
||||
|
|
@ -993,27 +993,27 @@ To clarify, let's consider the <tt>except</tt> feature again (<tt>%exception</tt
|
|||
<pre>
|
||||
// Define global exception handler
|
||||
%feature("except") {
|
||||
try {
|
||||
$action
|
||||
} catch (...) {
|
||||
croak("Unknown C++ exception");
|
||||
}
|
||||
try {
|
||||
$action
|
||||
} catch (...) {
|
||||
croak("Unknown C++ exception");
|
||||
}
|
||||
}
|
||||
|
||||
// Define exception handler for all clone methods to log the method calls
|
||||
%feature("except") *::clone() {
|
||||
try {
|
||||
logger.info("$action");
|
||||
$action
|
||||
} catch (...) {
|
||||
croak("Unknown C++ exception");
|
||||
}
|
||||
try {
|
||||
logger.info("$action");
|
||||
$action
|
||||
} catch (...) {
|
||||
croak("Unknown C++ exception");
|
||||
}
|
||||
}
|
||||
|
||||
... initial set of class declarations with clone methods ...
|
||||
|
||||
// clear the previously defined feature
|
||||
%feature("except","") *::clone();
|
||||
%feature("except", "") *::clone();
|
||||
|
||||
... final set of class declarations with clone methods ...
|
||||
</pre>
|
||||
|
|
@ -1027,8 +1027,8 @@ However, these clone methods will still have an exception handler (without loggi
|
|||
|
||||
<p>
|
||||
Note that clearing a feature is not always the same as disabling it.
|
||||
Clearing the feature above with <tt>%feature("except","") *::clone()</tt> is not the same as specifying
|
||||
<tt>%feature("except","0") *::clone()</tt>. The former will disable the feature for clone methods -
|
||||
Clearing the feature above with <tt>%feature("except", "") *::clone()</tt> is not the same as specifying
|
||||
<tt>%feature("except", "0") *::clone()</tt>. The former will disable the feature for clone methods -
|
||||
the feature is still a better match than the global feature.
|
||||
If on the other hand, no global exception handler had been defined at all,
|
||||
then clearing the feature would be the same as disabling it as no other feature would have matched.
|
||||
|
|
@ -1042,7 +1042,7 @@ For example the following attempt to clear the initial feature will not work:
|
|||
<div class="code">
|
||||
<pre>
|
||||
%feature("except") clone() { logger.info("$action"); $action }
|
||||
%feature("except","") *::clone();
|
||||
%feature("except", "") *::clone();
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -1053,7 +1053,7 @@ but this will:
|
|||
<div class="code">
|
||||
<pre>
|
||||
%feature("except") clone() { logger.info("$action"); $action }
|
||||
%feature("except","") clone();
|
||||
%feature("except", "") clone();
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -1066,8 +1066,8 @@ The three macros below show this for the "except" feature:
|
|||
<div class="code">
|
||||
<pre>
|
||||
#define %exception %feature("except")
|
||||
#define %noexception %feature("except","0")
|
||||
#define %clearexception %feature("except","")
|
||||
#define %noexception %feature("except", "0")
|
||||
#define %clearexception %feature("except", "")
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -1158,21 +1158,21 @@ in the Python module. You might use <tt>%feature</tt> to rewrite proxy/shadow cl
|
|||
<div class="code">
|
||||
<pre>
|
||||
%module example
|
||||
%rename(bar_id) bar(int,double);
|
||||
%rename(bar_id) bar(int, double);
|
||||
|
||||
// Rewrite bar() to allow some nice overloading
|
||||
|
||||
%feature("shadow") Foo::bar(int) %{
|
||||
def bar(*args):
|
||||
if len(args) == 3:
|
||||
return apply(examplec.Foo_bar_id,args)
|
||||
return apply(examplec.Foo_bar,args)
|
||||
return apply(examplec.Foo_bar_id, args)
|
||||
return apply(examplec.Foo_bar, args)
|
||||
%}
|
||||
|
||||
class Foo {
|
||||
public:
|
||||
int bar(int x);
|
||||
int bar(int x, double y);
|
||||
int bar(int x);
|
||||
int bar(int x, double y);
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -174,6 +174,9 @@
|
|||
|
||||
<p><a name="D_class_code_typemaps"></a><tt>dconstructor</tt>, <tt>ddestructor</tt>, <tt>ddispose</tt> and <tt>ddispose_derived</tt> are used to generate the class constructor, destructor and <tt>dispose()</tt> method, respectively. The auxiliary code for handling the pointer to the C++ object is stored in <tt>dbody</tt> and <tt>dbody_derived</tt>. You can override them for specific types.</p>
|
||||
|
||||
<p>
|
||||
Code can also be injected into the D proxy class using <tt>%proxycode</tt>.
|
||||
</p>
|
||||
|
||||
<H3><a name="D_special_variables">22.3.7 Special variable macros</a></H3>
|
||||
|
||||
|
|
@ -229,8 +232,9 @@ void foo(SomeClass arg) {
|
|||
|
||||
%newobject bar();
|
||||
SomeClass *bar();
|
||||
%}</pre></div>
|
||||
<p>The code generated for <tt>foo()</tt> and <tt>bar()</tt> looks like this:</p>
|
||||
%}
|
||||
</pre></div>
|
||||
<p>The code generated for <tt>foo()</tt> and <tt>bar()</tt> looks like this:</p>
|
||||
<div class="targetlang"><pre>
|
||||
SomeClass foo() {
|
||||
return new SomeClass(example_im.foo(), false);
|
||||
|
|
@ -421,7 +425,7 @@ struct A {
|
|||
|
||||
<p>As with any other language, the SWIG test-suite can be built for D using the <tt>*-d-test-suite</tt> targets of the top-level Makefile. By default, D1 is targeted, to build it with D2, use the optional <tt>D_VERSION</tt> variable, e.g. <tt>make check-d-test-suite D_VERSION=2</tt>.</p>
|
||||
|
||||
<p>Note: If you want to use GDC on Linux or another platform which requires you to link <tt>libdl</tt> for dynamically loading the shared library, you might have to add <tt>-ldl</tt> manually to the <tt>d_compile</tt> target in <tt>Examples/Makefile</tt>, because GDC does not currently honor the <tt>pragma(lib,...)</tt> statement.</p>
|
||||
<p>Note: If you want to use GDC on Linux or another platform which requires you to link <tt>libdl</tt> for dynamically loading the shared library, you might have to add <tt>-ldl</tt> manually to the <tt>d_compile</tt> target in <tt>Examples/Makefile</tt>, because GDC does not currently honor the <tt>pragma(lib, ...)</tt> statement.</p>
|
||||
|
||||
|
||||
<H2><a name="D_typemap_examples">22.9 D Typemap examples</a></H2>
|
||||
|
|
|
|||
|
|
@ -243,7 +243,7 @@ of <tt>swig.swg</tt> looks like this:
|
|||
|
||||
/* Access control directives */
|
||||
|
||||
#define %immutable %feature("immutable","1")
|
||||
#define %immutable %feature("immutable", "1")
|
||||
#define %mutable %feature("immutable")
|
||||
|
||||
/* Directives for callback functions */
|
||||
|
|
@ -306,7 +306,7 @@ datatype such as <tt>int</tt> or <tt>void</tt>. <tt><em>type</em></tt> may be
|
|||
qualified with a qualifier such as <tt>const</tt> or <tt>volatile</tt>. <tt><em>declarator</em></tt>
|
||||
is a name with additional type-construction modifiers attached to it (pointers, arrays, references,
|
||||
functions, etc.). Examples of declarators include <tt>*x</tt>, <tt>**x</tt>, <tt>x[20]</tt>, and
|
||||
<tt>(*x)(int,double)</tt>. The <tt><em>initializer</em></tt> may be a value assigned using <tt>=</tt> or
|
||||
<tt>(*x)(int, double)</tt>. The <tt><em>initializer</em></tt> may be a value assigned using <tt>=</tt> or
|
||||
body of code enclosed in braces <tt>{ ... }</tt>.
|
||||
</p>
|
||||
|
||||
|
|
@ -372,7 +372,7 @@ For example, in an old C program, you might see things like this:
|
|||
|
||||
<div class="code">
|
||||
<pre>
|
||||
foo(a,b) {
|
||||
foo(a, b) {
|
||||
...
|
||||
}
|
||||
</pre>
|
||||
|
|
@ -516,8 +516,8 @@ $ swig -c++ -python -debug-module 4 example.i
|
|||
+++ cdecl ----------------------------------------
|
||||
| sym:name - "move"
|
||||
| name - "move"
|
||||
| decl - "f(double,double)."
|
||||
| parms - double ,double
|
||||
| decl - "f(double, double)."
|
||||
| parms - double, double
|
||||
| type - "void"
|
||||
| sym:symtab - 0x40194140
|
||||
|
|
||||
|
|
@ -729,7 +729,7 @@ For instance, the following example uses <tt>%rename</tt> in reverse to generate
|
|||
<div class="code">
|
||||
<pre>
|
||||
%rename(foo) foo_i(int);
|
||||
%rename(foo) foo_d(double;
|
||||
%rename(foo) foo_d(double);
|
||||
|
||||
void foo_i(int);
|
||||
void foo_d(double);
|
||||
|
|
@ -772,8 +772,8 @@ low-level <tt>%feature</tt> directive. For example:
|
|||
...
|
||||
class Foo {
|
||||
public:
|
||||
Object *getitem(int index) throws(badindex);
|
||||
...
|
||||
Object *getitem(int index) throws(badindex);
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -826,7 +826,7 @@ transformed. For example, suppose you are wrapping a class like this:
|
|||
<pre>
|
||||
class Foo {
|
||||
public:
|
||||
virtual int *bar(int x);
|
||||
virtual int *bar(int x);
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1381,14 +1381,14 @@ List *l = (some list);
|
|||
Iterator i;
|
||||
|
||||
for (i = First(l); i.item; i = Next(i)) {
|
||||
Printf(stdout,"%s\n", i.item);
|
||||
Printf(stdout, "%s\n", i.item);
|
||||
}
|
||||
|
||||
Hash *h = (some hash);
|
||||
Iterator j;
|
||||
|
||||
for (j = First(j); j.item; j= Next(j)) {
|
||||
Printf(stdout,"%s : %s\n", j.key, j.item);
|
||||
Printf(stdout, "%s : %s\n", j.key, j.item);
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1414,7 +1414,7 @@ operators have the same meaning.
|
|||
</div>
|
||||
|
||||
<p>
|
||||
<b><tt>int Printv(String_or_FILE *f, String_or_char *arg1,..., NULL)</tt></b>
|
||||
<b><tt>int Printv(String_or_FILE *f, String_or_char *arg1, ..., NULL)</tt></b>
|
||||
</p>
|
||||
|
||||
<div class="indent">
|
||||
|
|
@ -1469,7 +1469,7 @@ Same as the C <tt>ungetc()</tt> function.
|
|||
|
||||
<div class="indent">
|
||||
Same as the C <tt>seek()</tt> function. <tt>offset</tt> is the number
|
||||
of bytes. <tt>whence</tt> is one of <tt>SEEK_SET</tt>,<tt>SEEK_CUR</tt>,
|
||||
of bytes. <tt>whence</tt> is one of <tt>SEEK_SET</tt>, <tt>SEEK_CUR</tt>,
|
||||
or <tt>SEEK_END</tt>..
|
||||
</div>
|
||||
|
||||
|
|
@ -1515,9 +1515,9 @@ common to see small code fragments of code generated using code like this:
|
|||
<pre>
|
||||
/* Print into a string */
|
||||
String *s = NewString("");
|
||||
Printf(s,"Hello\n");
|
||||
Printf(s, "Hello\n");
|
||||
for (i = 0; i < 10; i++) {
|
||||
Printf(s,"%d\n", i);
|
||||
Printf(s, "%d\n", i);
|
||||
}
|
||||
...
|
||||
/* Print string into a file */
|
||||
|
|
@ -1674,10 +1674,10 @@ Since parse tree nodes are just hash tables, attributes are accessed using the <
|
|||
<div class="code">
|
||||
<pre>
|
||||
int functionHandler(Node *n) {
|
||||
String *name = Getattr(n,"name");
|
||||
String *symname = Getattr(n,"sym:name");
|
||||
SwigType *type = Getattr(n,"type");
|
||||
...
|
||||
String *name = Getattr(n, "name");
|
||||
String *symname = Getattr(n, "sym:name");
|
||||
SwigType *type = Getattr(n, "type");
|
||||
...
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1691,7 +1691,7 @@ For example:
|
|||
<div class="code">
|
||||
<pre>
|
||||
...
|
||||
Setattr(n,"python:docstring", doc); /* Store docstring */
|
||||
Setattr(n, "python:docstring", doc); /* Store docstring */
|
||||
...
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1702,9 +1702,9 @@ A quick way to check the value of an attribute is to use the <tt>checkAttribute(
|
|||
|
||||
<div class="code">
|
||||
<pre>
|
||||
if (checkAttribute(n,"storage","virtual")) {
|
||||
/* n is virtual */
|
||||
...
|
||||
if (checkAttribute(n, "storage", "virtual")) {
|
||||
/* n is virtual */
|
||||
...
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1723,7 +1723,7 @@ the following functions are used:
|
|||
<div class="indent">
|
||||
Saves a copy of attributes <tt>name1</tt>, <tt>name2</tt>, etc. from node <tt>n</tt>.
|
||||
Copies of the attributes are actually resaved in the node in a different namespace which is
|
||||
set by the <tt>ns</tt> argument. For example, if you call <tt>Swig_save("foo",n,"type",NIL)</tt>,
|
||||
set by the <tt>ns</tt> argument. For example, if you call <tt>Swig_save("foo", n, "type", NIL)</tt>,
|
||||
then the "type" attribute will be copied and saved as "foo:type". The namespace name itself is stored in
|
||||
the "view" attribute of the node. If necessary, this can be examined to find out where previous
|
||||
values of attributes might have been saved.
|
||||
|
|
@ -1750,17 +1750,17 @@ Calls can be nested if necessary. Here is an example that shows how the functio
|
|||
<div class="code">
|
||||
<pre>
|
||||
int variableHandler(Node *n) {
|
||||
Swig_save("variableHandler",n,"type","sym:name",NIL);
|
||||
String *symname = Getattr(n,"sym:name");
|
||||
SwigType *type = Getattr(n,"type");
|
||||
...
|
||||
Append(symname,"_global"); // Change symbol name
|
||||
SwigType_add_pointer(type); // Add pointer
|
||||
...
|
||||
generate wrappers
|
||||
...
|
||||
Swig_restore(n); // Restore original values
|
||||
return SWIG_OK;
|
||||
Swig_save("variableHandler", n, "type", "sym:name", NIL);
|
||||
String *symname = Getattr(n, "sym:name");
|
||||
SwigType *type = Getattr(n, "type");
|
||||
...
|
||||
Append(symname, "_global"); // Change symbol name
|
||||
SwigType_add_pointer(type); // Add pointer
|
||||
...
|
||||
generate wrappers
|
||||
...
|
||||
Swig_restore(n); // Restore original values
|
||||
return SWIG_OK;
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1808,7 +1808,7 @@ C datatype SWIG encoding (strings)
|
|||
int "int"
|
||||
int * "p.int"
|
||||
const int * "p.q(const).int"
|
||||
int (*x)(int,double) "p.f(int,double).int"
|
||||
int (*x)(int, double) "p.f(int, double).int"
|
||||
int [20][30] "a(20).a(30).int"
|
||||
int (F::*)(int) "m(F).f(int).int"
|
||||
vector<int> * "p.vector<(int)>"
|
||||
|
|
@ -1817,8 +1817,8 @@ vector<int> * "p.vector<(int)>"
|
|||
|
||||
<p>
|
||||
Reading the SWIG encoding is often easier than figuring out the C code---just
|
||||
read it from left to right. For a type of "p.f(int,double).int" is
|
||||
a "pointer to a function(int,double) that returns int".
|
||||
read it from left to right. For a type of "p.f(int, double).int" is
|
||||
a "pointer to a function(int, double) that returns int".
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
|
@ -1854,7 +1854,7 @@ an extremely perverted example:
|
|||
|
||||
<div class="diagram">
|
||||
<pre>
|
||||
`p.a(10).p.f(int,p.f(int).int)` foo(int, int (*x)(int));
|
||||
`p.a(10).p.f(int, p.f(int).int)` foo(int, int (*x)(int));
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -1864,7 +1864,7 @@ This corresponds to the immediately obvious C declaration:
|
|||
|
||||
<div class="diagram">
|
||||
<pre>
|
||||
(*(*foo(int,int (*)(int)))[10])(int,int (*)(int));
|
||||
(*(*foo(int, int (*)(int)))[10])(int, int (*)(int));
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -1947,7 +1947,7 @@ Returns number of array dimensions of <tt>ty</tt>.
|
|||
</div>
|
||||
|
||||
<p>
|
||||
<b><tt>String* SwigType_array_getdim(SwigType *ty,int n)</tt></b>
|
||||
<b><tt>String* SwigType_array_getdim(SwigType *ty, int n)</tt></b>
|
||||
</p>
|
||||
|
||||
<div class="indent">
|
||||
|
|
@ -2375,10 +2375,10 @@ code like this:
|
|||
Parm *parms;
|
||||
Parm *p;
|
||||
for (p = parms; p; p = nextSibling(p)) {
|
||||
SwigType *type = Getattr(p,"type");
|
||||
String *name = Getattr(p,"name");
|
||||
String *value = Getattr(p,"value");
|
||||
...
|
||||
SwigType *type = Getattr(p, "type");
|
||||
String *name = Getattr(p, "name");
|
||||
String *value = Getattr(p, "value");
|
||||
...
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2534,10 +2534,10 @@ also return a pointer to the base class (<tt>Language</tt>) so that only the int
|
|||
</p>
|
||||
|
||||
<p>
|
||||
Save the code for your language module in a file named "<tt>python.cxx</tt>" and.
|
||||
Save the code for your language module in a file named "<tt>python.cxx</tt>" and
|
||||
place this file in the <tt>Source/Modules</tt> directory of the SWIG distribution.
|
||||
To ensure that your module is compiled into SWIG along with the other language modules,
|
||||
modify the file <tt>Source/Modules/Makefile.am</tt> to include the additional source
|
||||
modify the file <tt>Source/Makefile.am</tt> to include the additional source
|
||||
files. In addition, modify the file <tt>Source/Modules/swigmain.cxx</tt>
|
||||
with an additional command line option that activates the module. Read the source---it's straightforward.
|
||||
</p>
|
||||
|
|
@ -2593,7 +2593,7 @@ command line options, simply use code similar to this:
|
|||
void Language::main(int argc, char *argv[]) {
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (argv[i]) {
|
||||
if(strcmp(argv[i],"-interface") == 0) {
|
||||
if (strcmp(argv[i], "-interface") == 0) {
|
||||
if (argv[i+1]) {
|
||||
interface = NewString(argv[i+1]);
|
||||
Swig_mark_arg(i);
|
||||
|
|
@ -2602,7 +2602,7 @@ void Language::main(int argc, char *argv[]) {
|
|||
} else {
|
||||
Swig_arg_error();
|
||||
}
|
||||
} else if (strcmp(argv[i],"-globals") == 0) {
|
||||
} else if (strcmp(argv[i], "-globals") == 0) {
|
||||
if (argv[i+1]) {
|
||||
global_name = NewString(argv[i+1]);
|
||||
Swig_mark_arg(i);
|
||||
|
|
@ -2611,14 +2611,14 @@ void Language::main(int argc, char *argv[]) {
|
|||
} else {
|
||||
Swig_arg_error();
|
||||
}
|
||||
} else if ( (strcmp(argv[i],"-proxy") == 0)) {
|
||||
} else if ((strcmp(argv[i], "-proxy") == 0)) {
|
||||
proxy_flag = 1;
|
||||
Swig_mark_arg(i);
|
||||
} else if (strcmp(argv[i],"-keyword") == 0) {
|
||||
} else if (strcmp(argv[i], "-keyword") == 0) {
|
||||
use_kw = 1;
|
||||
Swig_mark_arg(i);
|
||||
} else if (strcmp(argv[i],"-help") == 0) {
|
||||
fputs(usage,stderr);
|
||||
} else if (strcmp(argv[i], "-help") == 0) {
|
||||
fputs(usage, stderr);
|
||||
}
|
||||
...
|
||||
}
|
||||
|
|
@ -2650,19 +2650,19 @@ insert some code like this:
|
|||
<div class="code">
|
||||
<pre>
|
||||
void main(int argc, char *argv[]) {
|
||||
... command line options ...
|
||||
... command line options ...
|
||||
|
||||
/* Set language-specific subdirectory in SWIG library */
|
||||
SWIG_library_directory("python");
|
||||
/* Set language-specific subdirectory in SWIG library */
|
||||
SWIG_library_directory("python");
|
||||
|
||||
/* Set language-specific preprocessing symbol */
|
||||
Preprocessor_define("SWIGPYTHON 1", 0);
|
||||
/* Set language-specific preprocessing symbol */
|
||||
Preprocessor_define("SWIGPYTHON 1", 0);
|
||||
|
||||
/* Set language-specific configuration file */
|
||||
SWIG_config_file("python.swg");
|
||||
/* Set language-specific configuration file */
|
||||
SWIG_config_file("python.swg");
|
||||
|
||||
/* Set typemap language (historical) */
|
||||
SWIG_typemap_lang("python");
|
||||
/* Set typemap language (historical) */
|
||||
SWIG_typemap_lang("python");
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2721,26 +2721,26 @@ An outline of <tt>top()</tt> might be as follows:
|
|||
<pre>
|
||||
int Python::top(Node *n) {
|
||||
|
||||
/* Get the module name */
|
||||
String *module = Getattr(n,"name");
|
||||
/* Get the module name */
|
||||
String *module = Getattr(n, "name");
|
||||
|
||||
/* Get the output file name */
|
||||
String *outfile = Getattr(n,"outfile");
|
||||
/* Get the output file name */
|
||||
String *outfile = Getattr(n, "outfile");
|
||||
|
||||
/* Initialize I/O (see next section) */
|
||||
...
|
||||
/* Initialize I/O (see next section) */
|
||||
...
|
||||
|
||||
/* Output module initialization code */
|
||||
...
|
||||
/* Output module initialization code */
|
||||
...
|
||||
|
||||
/* Emit code for children */
|
||||
Language::top(n);
|
||||
/* Emit code for children */
|
||||
Language::top(n);
|
||||
|
||||
...
|
||||
/* Cleanup files */
|
||||
...
|
||||
...
|
||||
/* Cleanup files */
|
||||
...
|
||||
|
||||
return SWIG_OK;
|
||||
return SWIG_OK;
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2777,62 +2777,62 @@ such as:
|
|||
<pre>
|
||||
class PYTHON : public Language {
|
||||
protected:
|
||||
/* General DOH objects used for holding the strings */
|
||||
File *f_begin;
|
||||
File *f_runtime;
|
||||
File *f_header;
|
||||
File *f_wrappers;
|
||||
File *f_init;
|
||||
/* General DOH objects used for holding the strings */
|
||||
File *f_begin;
|
||||
File *f_runtime;
|
||||
File *f_header;
|
||||
File *f_wrappers;
|
||||
File *f_init;
|
||||
|
||||
public:
|
||||
...
|
||||
...
|
||||
|
||||
};
|
||||
|
||||
int Python::top(Node *n) {
|
||||
|
||||
...
|
||||
...
|
||||
|
||||
/* Initialize I/O */
|
||||
f_begin = NewFile(outfile, "w", SWIG_output_files());
|
||||
if (!f_begin) {
|
||||
FileErrorDisplay(outfile);
|
||||
SWIG_exit(EXIT_FAILURE);
|
||||
}
|
||||
f_runtime = NewString("");
|
||||
f_init = NewString("");
|
||||
f_header = NewString("");
|
||||
f_wrappers = NewString("");
|
||||
/* Initialize I/O */
|
||||
f_begin = NewFile(outfile, "w", SWIG_output_files());
|
||||
if (!f_begin) {
|
||||
FileErrorDisplay(outfile);
|
||||
SWIG_exit(EXIT_FAILURE);
|
||||
}
|
||||
f_runtime = NewString("");
|
||||
f_init = NewString("");
|
||||
f_header = NewString("");
|
||||
f_wrappers = NewString("");
|
||||
|
||||
/* Register file targets with the SWIG file handler */
|
||||
Swig_register_filebyname("begin", f_begin);
|
||||
Swig_register_filebyname("header", f_header);
|
||||
Swig_register_filebyname("wrapper", f_wrappers);
|
||||
Swig_register_filebyname("runtime", f_runtime);
|
||||
Swig_register_filebyname("init", f_init);
|
||||
/* Register file targets with the SWIG file handler */
|
||||
Swig_register_filebyname("begin", f_begin);
|
||||
Swig_register_filebyname("header", f_header);
|
||||
Swig_register_filebyname("wrapper", f_wrappers);
|
||||
Swig_register_filebyname("runtime", f_runtime);
|
||||
Swig_register_filebyname("init", f_init);
|
||||
|
||||
/* Output module initialization code */
|
||||
Swig_banner(f_begin);
|
||||
...
|
||||
/* Output module initialization code */
|
||||
Swig_banner(f_begin);
|
||||
...
|
||||
|
||||
/* Emit code for children */
|
||||
Language::top(n);
|
||||
/* Emit code for children */
|
||||
Language::top(n);
|
||||
|
||||
...
|
||||
/* Write all to the file */
|
||||
Dump(f_runtime, f_begin);
|
||||
Dump(f_header, f_begin);
|
||||
Dump(f_wrappers, f_begin);
|
||||
Wrapper_pretty_print(f_init, f_begin);
|
||||
...
|
||||
/* Write all to the file */
|
||||
Dump(f_runtime, f_begin);
|
||||
Dump(f_header, f_begin);
|
||||
Dump(f_wrappers, f_begin);
|
||||
Wrapper_pretty_print(f_init, f_begin);
|
||||
|
||||
/* Cleanup files */
|
||||
Delete(f_runtime);
|
||||
Delete(f_header);
|
||||
Delete(f_wrappers);
|
||||
Delete(f_init);
|
||||
Delete(f_begin);
|
||||
/* Cleanup files */
|
||||
Delete(f_runtime);
|
||||
Delete(f_header);
|
||||
Delete(f_wrappers);
|
||||
Delete(f_init);
|
||||
Delete(f_begin);
|
||||
|
||||
return SWIG_OK;
|
||||
return SWIG_OK;
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2858,15 +2858,15 @@ A simple modification to write some basic details to the wrapper looks like this
|
|||
<pre>
|
||||
int Python::functionWrapper(Node *n) {
|
||||
/* Get some useful attributes of this function */
|
||||
String *name = Getattr(n,"sym:name");
|
||||
SwigType *type = Getattr(n,"type");
|
||||
ParmList *parms = Getattr(n,"parms");
|
||||
String *name = Getattr(n, "sym:name");
|
||||
SwigType *type = Getattr(n, "type");
|
||||
ParmList *parms = Getattr(n, "parms");
|
||||
String *parmstr= ParmList_str_defaultargs(parms); // to string
|
||||
String *func = SwigType_str(type, NewStringf("%s(%s)", name, parmstr));
|
||||
String *action = Getattr(n,"wrap:action");
|
||||
String *action = Getattr(n, "wrap:action");
|
||||
|
||||
Printf(f_wrappers,"functionWrapper : %s\n", func);
|
||||
Printf(f_wrappers," action : %s\n", action);
|
||||
Printf(f_wrappers, "functionWrapper : %s\n", func);
|
||||
Printf(f_wrappers, " action : %s\n", action);
|
||||
return SWIG_OK;
|
||||
}
|
||||
</pre>
|
||||
|
|
@ -2881,13 +2881,13 @@ This will now produce some useful information within your wrapper file.
|
|||
functionWrapper : void delete_Shape(Shape *self)
|
||||
action : delete arg1;
|
||||
|
||||
functionWrapper : void Shape_x_set(Shape *self,double x)
|
||||
functionWrapper : void Shape_x_set(Shape *self, double x)
|
||||
action : if (arg1) (arg1)->x = arg2;
|
||||
|
||||
functionWrapper : double Shape_x_get(Shape *self)
|
||||
action : result = (double) ((arg1)->x);
|
||||
|
||||
functionWrapper : void Shape_y_set(Shape *self,double y)
|
||||
functionWrapper : void Shape_y_set(Shape *self, double y)
|
||||
action : if (arg1) (arg1)->y = arg2;
|
||||
...
|
||||
</pre>
|
||||
|
|
@ -2918,7 +2918,7 @@ In general most language wrappers look a little like this:
|
|||
</p>
|
||||
<div class="code">
|
||||
<pre>
|
||||
/* wrapper for TYPE3 some_function(TYPE1,TYPE2); */
|
||||
/* wrapper for TYPE3 some_function(TYPE1, TYPE2); */
|
||||
RETURN_TYPE _wrap_some_function(ARGS){
|
||||
TYPE1 arg1;
|
||||
TYPE2 arg2;
|
||||
|
|
@ -2929,7 +2929,7 @@ RETURN_TYPE _wrap_some_function(ARGS){
|
|||
if(ARG2 is not of TYPE2) goto fail;
|
||||
arg2=(convert ARG2);
|
||||
|
||||
result=some_function(arg1,arg2);
|
||||
result=some_function(arg1, arg2);
|
||||
|
||||
convert 'result' to whatever the language wants;
|
||||
|
||||
|
|
@ -2973,9 +2973,9 @@ There are a lot of issues to address.
|
|||
<pre>
|
||||
virtual int functionWrapper(Node *n) {
|
||||
/* get useful attributes */
|
||||
String *name = Getattr(n,"sym:name");
|
||||
SwigType *type = Getattr(n,"type");
|
||||
ParmList *parms = Getattr(n,"parms");
|
||||
String *name = Getattr(n, "sym:name");
|
||||
SwigType *type = Getattr(n, "type");
|
||||
ParmList *parms = Getattr(n, "parms");
|
||||
...
|
||||
|
||||
/* create the wrapper object */
|
||||
|
|
@ -2988,7 +2988,7 @@ virtual int functionWrapper(Node *n) {
|
|||
....
|
||||
|
||||
/* write the wrapper function definition */
|
||||
Printv(wrapper->def,"RETURN_TYPE ", wname, "(ARGS) {",NIL);
|
||||
Printv(wrapper->def, "RETURN_TYPE ", wname, "(ARGS) {", NIL);
|
||||
|
||||
/* if any additional local variable needed, add them now */
|
||||
...
|
||||
|
|
@ -3006,7 +3006,7 @@ virtual int functionWrapper(Node *n) {
|
|||
....
|
||||
|
||||
/* Emit the function call */
|
||||
emit_action(n,wrapper);
|
||||
emit_action(n, wrapper);
|
||||
|
||||
/* return value if necessary */
|
||||
....
|
||||
|
|
@ -3030,7 +3030,7 @@ virtual int functionWrapper(Node *n) {
|
|||
...
|
||||
|
||||
/* Dump the function out */
|
||||
Wrapper_print(wrapper,f_wrappers);
|
||||
Wrapper_print(wrapper, f_wrappers);
|
||||
|
||||
/* tidy up */
|
||||
Delete(wname);
|
||||
|
|
|
|||
|
|
@ -30,13 +30,14 @@
|
|||
<li><a href="#Guile_nn14">Smobs</a>
|
||||
<li><a href="#Guile_nn15">Garbage Collection</a>
|
||||
</ul>
|
||||
<li><a href="#Guile_nn16">Exception Handling</a>
|
||||
<li><a href="#Guile_nn17">Procedure documentation</a>
|
||||
<li><a href="#Guile_nn18">Procedures with setters</a>
|
||||
<li><a href="#Guile_nn19">GOOPS Proxy Classes</a>
|
||||
<li><a href="#Guile_nn16">Native Guile pointers</a>
|
||||
<li><a href="#Guile_nn17">Exception Handling</a>
|
||||
<li><a href="#Guile_nn18">Procedure documentation</a>
|
||||
<li><a href="#Guile_nn19">Procedures with setters</a>
|
||||
<li><a href="#Guile_nn20">GOOPS Proxy Classes</a>
|
||||
<ul>
|
||||
<li><a href="#Guile_nn20">Naming Issues</a>
|
||||
<li><a href="#Guile_nn21">Linking</a>
|
||||
<li><a href="#Guile_nn21">Naming Issues</a>
|
||||
<li><a href="#Guile_nn22">Linking</a>
|
||||
</ul>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
@ -453,7 +454,14 @@ is exactly like described in <a href="Customization.html#Customization_ownership
|
|||
Object ownership and %newobject</a> in the SWIG manual. All typemaps use an $owner var, and
|
||||
the guile module replaces $owner with 0 or 1 depending on feature:new.</p>
|
||||
|
||||
<H2><a name="Guile_nn16">24.8 Exception Handling</a></H2>
|
||||
<H2><a name="Guile_nn16">24.8 Native Guile pointers</a></H2>
|
||||
|
||||
|
||||
<p>
|
||||
In addition to SWIG smob pointers, <a href="https://www.gnu.org/software/guile/manual/html_node/Foreign-Pointers.html">Guile's native pointer type</a> are accepted as arguments to wrapped SWIG functions. This can be useful for passing <a href="https://www.gnu.org/software/guile/manual/html_node/Void-Pointers-and-Byte-Access.html#">pointers to bytevector data</a> to wrapped functions.
|
||||
</p>
|
||||
|
||||
<H2><a name="Guile_nn17">24.9 Exception Handling</a></H2>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -479,7 +487,7 @@ mapping:
|
|||
The default when not specified here is to use "swig-error".
|
||||
See Lib/exception.i for details.
|
||||
|
||||
<H2><a name="Guile_nn17">24.9 Procedure documentation</a></H2>
|
||||
<H2><a name="Guile_nn18">24.10 Procedure documentation</a></H2>
|
||||
|
||||
|
||||
<p>If invoked with the command-line option <code>-procdoc
|
||||
|
|
@ -514,7 +522,7 @@ like this:
|
|||
typemap argument <code>doc</code>. See <code>Lib/guile/typemaps.i</code> for
|
||||
details.
|
||||
|
||||
<H2><a name="Guile_nn18">24.10 Procedures with setters</a></H2>
|
||||
<H2><a name="Guile_nn19">24.11 Procedures with setters</a></H2>
|
||||
|
||||
|
||||
<p>For global variables, SWIG creates a single wrapper procedure
|
||||
|
|
@ -542,7 +550,7 @@ struct members, the procedures <code>(<var>struct</var>-<var>member</var>-get
|
|||
pointer)</code> and <code>(<var>struct-member</var>-set pointer
|
||||
value)</code> are <em>not</em> generated.
|
||||
|
||||
<H2><a name="Guile_nn19">24.11 GOOPS Proxy Classes</a></H2>
|
||||
<H2><a name="Guile_nn20">24.12 GOOPS Proxy Classes</a></H2>
|
||||
|
||||
|
||||
<p>SWIG can also generate classes and generic functions for use with
|
||||
|
|
@ -688,7 +696,7 @@ Notice that <Foo> is used before it is defined. The fix is to just put th
|
|||
<code>%import "foo.h"</code> before the <code>%inline</code> block.
|
||||
</p>
|
||||
|
||||
<H3><a name="Guile_nn20">24.11.1 Naming Issues</a></H3>
|
||||
<H3><a name="Guile_nn21">24.12.1 Naming Issues</a></H3>
|
||||
|
||||
|
||||
<p>As you can see in the example above, there are potential naming conflicts. The default exported
|
||||
|
|
@ -725,7 +733,7 @@ guile-modules. For example,</p>
|
|||
(use-modules ((Test) #:renamer (symbol-prefix-proc 'goops:)))
|
||||
</pre></div>
|
||||
|
||||
<H3><a name="Guile_nn21">24.11.2 Linking</a></H3>
|
||||
<H3><a name="Guile_nn22">24.12.2 Linking</a></H3>
|
||||
|
||||
|
||||
<p>The guile-modules generated above all need to be linked together. GOOPS support requires
|
||||
|
|
|
|||
|
|
@ -251,7 +251,7 @@ unix > <b>ld -G example.o example_wrap.o -o example.so</b> # This is for Sola
|
|||
unix > <b>perl5.003
|
||||
use example;
|
||||
print example::fact(4), "\n";
|
||||
print example::my_mod(23,7), "\n";
|
||||
print example::my_mod(23, 7), "\n";
|
||||
print $example::My_variable + 4.5, "\n";
|
||||
<ctrl-d></b>
|
||||
24
|
||||
|
|
@ -279,7 +279,7 @@ Type "copyright", "credits" or "license" for more information.
|
|||
>>> <b>import example</b>
|
||||
>>> <b>example.fact(4)</b>
|
||||
24
|
||||
>>> <b>example.my_mod(23,7)</b>
|
||||
>>> <b>example.my_mod(23, 7)</b>
|
||||
2
|
||||
>>> <b>example.cvar.My_variable + 4.5</b>
|
||||
7.5
|
||||
|
|
@ -303,7 +303,7 @@ unix > <b>ld -G example.o example_wrap.o -o example.so</b>
|
|||
unix > <b>perl5.003
|
||||
use example;
|
||||
print example::fact(4), "\n";
|
||||
print example::my_mod(23,7), "\n";
|
||||
print example::my_mod(23, 7), "\n";
|
||||
print $example::My_variable + 4.5, "\n";
|
||||
<ctrl-d></b>
|
||||
24
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -300,34 +300,34 @@ extern bool example_initialize(JSGlobalContextRef context);
|
|||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
// Initialize GTK+
|
||||
gtk_init(&argc, &argv);
|
||||
// Initialize GTK+
|
||||
gtk_init(&argc, &argv);
|
||||
|
||||
...
|
||||
...
|
||||
|
||||
// Create a browser instance
|
||||
WebKitWebView *webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
|
||||
WebFrame *webframe = webkit_web_view_get_main_frame(webView);
|
||||
JSGlobalContextRef context = webkit_web_frame_get_global_context(webFrame);
|
||||
JSObjectRef global = JSContextGetGlobalObject(context);
|
||||
// Create a browser instance
|
||||
WebKitWebView *webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
|
||||
WebFrame *webframe = webkit_web_view_get_main_frame(webView);
|
||||
JSGlobalContextRef context = webkit_web_frame_get_global_context(webFrame);
|
||||
JSObjectRef global = JSContextGetGlobalObject(context);
|
||||
|
||||
JSObjectRef exampleModule;
|
||||
example_initialize(context, &exampleModule);
|
||||
JSStringRef jsName = JSStringCreateWithUTF8CString("example");
|
||||
JSObjectSetProperty(context, global, jsName, exampleModule, kJSPropertyAttributeReadOnly, NULL);
|
||||
JSStringRelease(jsName);
|
||||
JSObjectRef exampleModule;
|
||||
example_initialize(context, &exampleModule);
|
||||
JSStringRef jsName = JSStringCreateWithUTF8CString("example");
|
||||
JSObjectSetProperty(context, global, jsName, exampleModule, kJSPropertyAttributeReadOnly, NULL);
|
||||
JSStringRelease(jsName);
|
||||
|
||||
...
|
||||
...
|
||||
|
||||
// Load a web page into the browser instance
|
||||
webkit_web_view_load_uri(webView, "http://www.webkitgtk.org/");
|
||||
// Load a web page into the browser instance
|
||||
webkit_web_view_load_uri(webView, "http://www.webkitgtk.org/");
|
||||
|
||||
...
|
||||
...
|
||||
|
||||
// Run the main GTK+ event loop
|
||||
gtk_main();
|
||||
// Run the main GTK+ event loop
|
||||
gtk_main();
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -415,7 +415,7 @@ open new windows, and many more things.
|
|||
var example = require("example");
|
||||
var x = 18;
|
||||
var y = 24;
|
||||
var z = example.gcd(x,y);
|
||||
var z = example.gcd(x, y);
|
||||
document.querySelector('#x').innerHTML = x;
|
||||
document.querySelector('#y').innerHTML = y;
|
||||
document.querySelector('#z').innerHTML = z;
|
||||
|
|
@ -467,7 +467,7 @@ var example = require("./build/Release/example");
|
|||
// calling the global method
|
||||
var x = 42;
|
||||
var y = 105;
|
||||
var g = example.gcd(x,y);
|
||||
var g = example.gcd(x, y);
|
||||
|
||||
// Accessing the global variable
|
||||
var f = example.Foo;
|
||||
|
|
@ -742,7 +742,7 @@ t_register.replace("$jsparent", state.clazz(NAME_MANGLED))
|
|||
.trim().
|
||||
print(f_init_static_wrappers);</pre>
|
||||
</div>
|
||||
<p>A code template is registered with the <em>JSEmitter</em> via <code>fragment(name, "template")</code>, e.g.,</p>
|
||||
<p>A code template is registered with the <em>JSEmitter</em> via <code>fragment(name, "template")</code>, e.g., </p>
|
||||
<div class="code">
|
||||
<pre>
|
||||
%fragment ("jsc_variable_declaration", "templates")
|
||||
|
|
@ -921,7 +921,7 @@ state.clazz(NAME, Getattr(n, "sym:name"));</pre>
|
|||
<p>Applications with an embedded JavascriptCore should be able to present detailed exception messages that occur in the Javascript engine. Below is an example derived from code provided by Brian Barnes on how these exception details can be extracted.</p>
|
||||
<div class="code">
|
||||
<pre>
|
||||
void script_exception_to_string(JSContextRef js_context,JSValueRef exception_value_ref,char* return_error_string, int return_error_string_max_length)
|
||||
void script_exception_to_string(JSContextRef js_context, JSValueRef exception_value_ref, char* return_error_string, int return_error_string_max_length)
|
||||
{
|
||||
JSObjectRef exception_object;
|
||||
JSValueRef value_ref;
|
||||
|
|
@ -933,7 +933,7 @@ void script_exception_to_string(JSContextRef js_context,JSValueRef exception_val
|
|||
exception_object = JSValueToObject(js_context, exception_value_ref, NULL);
|
||||
|
||||
/* source url */
|
||||
strcpy(return_error_string,"[");
|
||||
strcpy(return_error_string, "[");
|
||||
jsstring_property_name = JSStringCreateWithUTF8CString("sourceURL");
|
||||
value_ref = JSObjectGetProperty(js_context, exception_object, jsstring_property_name, &temporary_exception);
|
||||
JSStringRelease(jsstring_property_name);
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ this module is in generating pointers to primitive datatypes such as
|
|||
</p>
|
||||
|
||||
<p>
|
||||
<b><tt>%pointer_functions(type,name)</tt></b>
|
||||
<b><tt>%pointer_functions(type, name)</tt></b>
|
||||
</p>
|
||||
|
||||
<div class="indent">
|
||||
|
|
@ -195,7 +195,7 @@ Now, in Python:
|
|||
<pre>
|
||||
>>> import example
|
||||
>>> c = example.new_intp() # Create an "int" for storing result
|
||||
>>> example.add(3,4,c) # Call function
|
||||
>>> example.add(3, 4, c) # Call function
|
||||
>>> example.intp_value(c) # Dereference
|
||||
7
|
||||
>>> example.delete_intp(c) # Delete
|
||||
|
|
@ -205,7 +205,7 @@ Now, in Python:
|
|||
</div>
|
||||
|
||||
<p>
|
||||
<b><tt>%pointer_class(type,name)</tt></b>
|
||||
<b><tt>%pointer_class(type, name)</tt></b>
|
||||
</p>
|
||||
|
||||
<div class="indent">
|
||||
|
|
@ -218,13 +218,13 @@ interface is as follows:
|
|||
<div class="code">
|
||||
<pre>
|
||||
struct name {
|
||||
name(); // Create pointer object
|
||||
~name(); // Delete pointer object
|
||||
void assign(type value); // Assign value
|
||||
type value(); // Get value
|
||||
type *cast(); // Cast the pointer to original type
|
||||
static name *frompointer(type *); // Create class wrapper from existing
|
||||
// pointer
|
||||
name(); // Create pointer object
|
||||
~name(); // Delete pointer object
|
||||
void assign(type value); // Assign value
|
||||
type value(); // Get value
|
||||
type *cast(); // Cast the pointer to original type
|
||||
static name *frompointer(type *); // Create class wrapper from existing
|
||||
// pointer
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -275,7 +275,7 @@ Now, in Python (using proxy classes)
|
|||
<pre>
|
||||
>>> import example
|
||||
>>> c = example.intp() # Create an "int" for storing result
|
||||
>>> example.add(3,4,c) # Call function
|
||||
>>> example.add(3, 4, c) # Call function
|
||||
>>> c.value() # Dereference
|
||||
7
|
||||
</pre>
|
||||
|
|
@ -331,7 +331,7 @@ raw C array data.
|
|||
</p>
|
||||
|
||||
<p>
|
||||
<b><tt>%array_functions(type,name)</tt></b>
|
||||
<b><tt>%array_functions(type, name)</tt></b>
|
||||
</p>
|
||||
|
||||
<div class="indent">
|
||||
|
|
@ -384,10 +384,10 @@ function like this:
|
|||
<div class="code">
|
||||
<pre>
|
||||
void print_array(double x[10]) {
|
||||
int i;
|
||||
for (i = 0; i < 10; i++) {
|
||||
printf("[%d] = %g\n", i, x[i]);
|
||||
}
|
||||
int i;
|
||||
for (i = 0; i < 10; i++) {
|
||||
printf("[%d] = %g\n", i, x[i]);
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -413,18 +413,18 @@ Now, in a scripting language, you might write this:
|
|||
|
||||
<div class="code">
|
||||
<pre>
|
||||
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
|
||||
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
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<p>
|
||||
<b><tt>%array_class(type,name)</tt></b>
|
||||
<b><tt>%array_class(type, name)</tt></b>
|
||||
</p>
|
||||
<div class="indent">
|
||||
|
||||
|
|
@ -436,13 +436,13 @@ interface is as follows:
|
|||
<div class="code">
|
||||
<pre>
|
||||
struct name {
|
||||
name(int nelements); // Create an array
|
||||
~name(); // Delete array
|
||||
type getitem(int index); // Return item
|
||||
void setitem(int index, type value); // Set item
|
||||
type *cast(); // Cast to original type
|
||||
static name *frompointer(type *); // Create class wrapper from
|
||||
// existing pointer
|
||||
name(int nelements); // Create an array
|
||||
~name(); // Delete array
|
||||
type getitem(int index); // Return item
|
||||
void setitem(int index, type value); // Set item
|
||||
type *cast(); // Cast to original type
|
||||
static name *frompointer(type *); // Create class wrapper from
|
||||
// existing pointer
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -479,7 +479,7 @@ Allows you to do this:
|
|||
<pre>
|
||||
import example
|
||||
c = example.doubleArray(10) # Create double[10]
|
||||
for i in range(0,10):
|
||||
for i in range(0, 10):
|
||||
c[i] = 2*i # Assign values
|
||||
example.print_array(c) # Pass to C
|
||||
</pre>
|
||||
|
|
@ -507,7 +507,7 @@ This module defines macros for wrapping the low-level C memory allocation functi
|
|||
</p>
|
||||
|
||||
<p>
|
||||
<b><tt>%malloc(type [,name=type])</tt></b>
|
||||
<b><tt>%malloc(type [, name=type])</tt></b>
|
||||
</p>
|
||||
|
||||
<div class="indent">
|
||||
|
|
@ -530,7 +530,7 @@ is not a valid identifier (e.g., "<tt>int *</tt>", "<tt>double **</tt>", etc.).
|
|||
</div>
|
||||
|
||||
<p>
|
||||
<b><tt>%calloc(type [,name=type])</tt></b>
|
||||
<b><tt>%calloc(type [, name=type])</tt></b>
|
||||
</p>
|
||||
|
||||
<div class="indent">
|
||||
|
|
@ -551,7 +551,7 @@ If <tt>type</tt> is <tt>void</tt>, then the size parameter <tt>sz</tt> is requir
|
|||
</div>
|
||||
|
||||
<p>
|
||||
<b><tt>%realloc(type [,name=type])</tt></b>
|
||||
<b><tt>%realloc(type [, name=type])</tt></b>
|
||||
</p>
|
||||
|
||||
<div class="indent">
|
||||
|
|
@ -574,7 +574,7 @@ it holds 100 integers.
|
|||
</div>
|
||||
|
||||
<p>
|
||||
<b><tt>%free(type [,name=type])</tt></b>
|
||||
<b><tt>%free(type [, name=type])</tt></b>
|
||||
</p>
|
||||
|
||||
<div class="indent">
|
||||
|
|
@ -590,7 +590,7 @@ void free_<em>name</em>(<em>type</em> *ptr);
|
|||
</div>
|
||||
|
||||
<p>
|
||||
<b><tt>%sizeof(type [,name=type])</tt></b>
|
||||
<b><tt>%sizeof(type [, name=type])</tt></b>
|
||||
</p>
|
||||
|
||||
<div class="indent">
|
||||
|
|
@ -606,7 +606,7 @@ Creates the constant:
|
|||
</div>
|
||||
|
||||
<p>
|
||||
<b><tt>%allocators(type [,name=type])</tt></b>
|
||||
<b><tt>%allocators(type [, name=type])</tt></b>
|
||||
</p>
|
||||
|
||||
<div class="indent"><p>
|
||||
|
|
@ -716,14 +716,14 @@ Python example:
|
|||
<div class="targetlang">
|
||||
<pre>
|
||||
>>> a = intArray(10)
|
||||
>>> for i in range(0,10):
|
||||
>>> for i in range(0, 10):
|
||||
... a[i] = i
|
||||
>>> b = cdata(a,40)
|
||||
>>> b = cdata(a, 40)
|
||||
>>> b
|
||||
'\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04
|
||||
\x00\x00\x00\x05\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x00\x00\t'
|
||||
>>> c = intArray(10)
|
||||
>>> memmove(c,b)
|
||||
>>> memmove(c, b)
|
||||
>>> print c[4]
|
||||
4
|
||||
>>>
|
||||
|
|
@ -735,7 +735,7 @@ Since the size of data is not always known, the following macro is also defined:
|
|||
</p>
|
||||
|
||||
<p>
|
||||
<b><tt>%cdata(type [,name=type])</tt></b>
|
||||
<b><tt>%cdata(type [, name=type])</tt></b>
|
||||
</p>
|
||||
|
||||
<div class="indent">
|
||||
|
|
@ -855,7 +855,7 @@ Now, in the target language, you can use binary string data like this:
|
|||
<div class="code">
|
||||
<pre>
|
||||
>>> s = "H\x00\x15eg\x09\x20"
|
||||
>>> parity(s,0)
|
||||
>>> parity(s, 0)
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -874,9 +874,9 @@ If you have a function that allocates memory like this,
|
|||
<div class="code">
|
||||
<pre>
|
||||
char *foo() {
|
||||
char *result = (char *) malloc(...);
|
||||
...
|
||||
return result;
|
||||
char *result = (char *) malloc(...);
|
||||
...
|
||||
return result;
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -919,16 +919,16 @@ implementation:
|
|||
<div class="code">
|
||||
<pre>
|
||||
void get_path(char *s) {
|
||||
// Potential buffer overflow---uh, oh.
|
||||
sprintf(s,"%s/%s", base_directory, sub_directory);
|
||||
// Potential buffer overflow---uh, oh.
|
||||
sprintf(s, "%s/%s", base_directory, sub_directory);
|
||||
}
|
||||
...
|
||||
// Somewhere else in the C program
|
||||
{
|
||||
char path[1024];
|
||||
...
|
||||
get_path(path);
|
||||
...
|
||||
char path[1024];
|
||||
...
|
||||
get_path(path);
|
||||
...
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1236,8 +1236,8 @@ returned in a parameter of type <tt>char **</tt>. For example:
|
|||
<div class="code">
|
||||
<pre>
|
||||
void foo(char **s) {
|
||||
*s = (char *) malloc(64);
|
||||
sprintf(*s, "Hello world\n");
|
||||
*s = (char *) malloc(64);
|
||||
sprintf(*s, "Hello world\n");
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1284,10 +1284,10 @@ returned in two parameters of type <tt>char **</tt> and <tt>int *</tt>. For exa
|
|||
<div class="code">
|
||||
<pre>
|
||||
void foo(char **s, int *sz) {
|
||||
*s = (char *) malloc(64);
|
||||
*sz = 64;
|
||||
// Write some binary data
|
||||
...
|
||||
*s = (char *) malloc(64);
|
||||
*sz = 64;
|
||||
// Write some binary data
|
||||
...
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1337,7 +1337,7 @@ You could wrap it with a function like this:
|
|||
<div class="code">
|
||||
<pre>
|
||||
void my_get_data(char **result, int *len) {
|
||||
*result = get_data(len);
|
||||
*result = get_data(len);
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1385,16 +1385,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>
|
||||
|
||||
|
|
@ -1503,8 +1511,8 @@ instantiate different versions of <tt>vector</tt> for the types that you want to
|
|||
%include "std_vector.i"
|
||||
|
||||
namespace std {
|
||||
%template(vectori) vector<int>;
|
||||
%template(vectord) vector<double>;
|
||||
%template(vectori) vector<int>;
|
||||
%template(vectord) vector<double>;
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1554,19 +1562,19 @@ To illustrate the use of this library, consider the following functions:
|
|||
#include <numeric>
|
||||
|
||||
double average(std::vector<int> v) {
|
||||
return std::accumulate(v.begin(),v.end(),0.0)/v.size();
|
||||
return std::accumulate(v.begin(), v.end(), 0.0)/v.size();
|
||||
}
|
||||
|
||||
std::vector<double> half(const std::vector<double>& v) {
|
||||
std::vector<double> w(v);
|
||||
for (unsigned int i=0; i<w.size(); i++)
|
||||
w[i] /= 2.0;
|
||||
return w;
|
||||
std::vector<double> w(v);
|
||||
for (unsigned int i=0; i<w.size(); i++)
|
||||
w[i] /= 2.0;
|
||||
return w;
|
||||
}
|
||||
|
||||
void halve_in_place(std::vector<double>& v) {
|
||||
std::transform(v.begin(),v.end(),v.begin(),
|
||||
std::bind2nd(std::divides<double>(),2.0));
|
||||
std::transform(v.begin(), v.end(), v.begin(),
|
||||
std::bind2nd(std::divides<double>(), 2.0));
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1585,8 +1593,8 @@ To wrap with SWIG, you might write the following:
|
|||
%include "std_vector.i"
|
||||
// Instantiate templates used by example
|
||||
namespace std {
|
||||
%template(IntVector) vector<int>;
|
||||
%template(DoubleVector) vector<double>;
|
||||
%template(IntVector) vector<int>;
|
||||
%template(DoubleVector) vector<double>;
|
||||
}
|
||||
|
||||
// Include the header file with above prototypes
|
||||
|
|
@ -1602,20 +1610,20 @@ Now, to illustrate the behavior in the scripting interpreter, consider this Pyth
|
|||
<pre>
|
||||
>>> from example import *
|
||||
>>> iv = IntVector(4) # Create an vector<int>
|
||||
>>> for i in range(0,4):
|
||||
>>> for i in range(0, 4):
|
||||
... iv[i] = i
|
||||
>>> average(iv) # Call method
|
||||
1.5
|
||||
>>> average([0,1,2,3]) # Call with list
|
||||
>>> average([0, 1, 2, 3]) # Call with list
|
||||
1.5
|
||||
>>> half([1,2,3]) # Half a list
|
||||
(0.5,1.0,1.5)
|
||||
>>> halve_in_place([1,2,3]) # Oops
|
||||
>>> half([1, 2, 3]) # Half a list
|
||||
(0.5, 1.0, 1.5)
|
||||
>>> halve_in_place([1, 2, 3]) # Oops
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in ?
|
||||
TypeError: Type error. Expected _p_std__vectorTdouble_t
|
||||
>>> dv = DoubleVector(4)
|
||||
>>> for i in range(0,4):
|
||||
>>> for i in range(0, 4):
|
||||
... dv[i] = i
|
||||
>>> halve_in_place(dv) # Ok
|
||||
>>> for i in dv:
|
||||
|
|
@ -1629,7 +1637,7 @@ TypeError: Type error. Expected _p_std__vectorTdouble_t
|
|||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in ?
|
||||
File "example.py", line 81, in __setitem__
|
||||
def __setitem__(*args): return apply(examplec.DoubleVector___setitem__,args)
|
||||
def __setitem__(*args): return apply(examplec.DoubleVector___setitem__, args)
|
||||
IndexError: vector index out of range
|
||||
>>>
|
||||
</pre>
|
||||
|
|
@ -1645,7 +1653,7 @@ make sure you include the appropriate <tt>using</tt> or typedef directives. For
|
|||
%include "std_vector.i"
|
||||
|
||||
namespace std {
|
||||
%template(IntVector) vector<int>;
|
||||
%template(IntVector) vector<int>;
|
||||
}
|
||||
|
||||
using namespace std;
|
||||
|
|
@ -1903,7 +1911,7 @@ Adding the missing <tt>%shared_ptr</tt> macros will fix this:
|
|||
|
||||
<p>
|
||||
<b>Note:</b> There is somewhat limited support for <tt>%shared_ptr</tt> and the director feature
|
||||
and the degress of success varies among the different target languages.
|
||||
and the degrees of success varies among the different target languages.
|
||||
Please help to improve this support by providing patches with improvements.
|
||||
</p>
|
||||
|
||||
|
|
@ -2011,11 +2019,11 @@ For example:
|
|||
<pre>
|
||||
%include "exception.i"
|
||||
%exception std::vector::getitem {
|
||||
try {
|
||||
$action
|
||||
} catch (std::out_of_range& e) {
|
||||
SWIG_exception(SWIG_IndexError,const_cast<char*>(e.what()));
|
||||
}
|
||||
try {
|
||||
$action
|
||||
} catch (std::out_of_range& e) {
|
||||
SWIG_exception(SWIG_IndexError, const_cast<char*>(e.what()));
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -134,29 +137,31 @@ typedef int days;
|
|||
|
||||
struct bar {
|
||||
short p, q;
|
||||
char a, b;
|
||||
int *z[1000];
|
||||
struct bar * n;
|
||||
char a, b;
|
||||
int *z[1000];
|
||||
struct bar * n;
|
||||
};
|
||||
|
||||
struct bar * my_struct;
|
||||
|
||||
struct foo {
|
||||
int a;
|
||||
struct foo * b[100];
|
||||
|
||||
int a;
|
||||
struct foo * b[100];
|
||||
};
|
||||
|
||||
int pointer_func(void (*ClosureFun)( void* _fun, void* _data, void* _evt ), int p);
|
||||
|
||||
int func123(div_t * p,int **q[100],int r[][1000][10]);
|
||||
int func123(div_t * p, int **q[100], int r[][1000][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
|
||||
|
||||
|
|
@ -164,18 +169,20 @@ 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
|
||||
|
||||
(cl:defmacro defanonenum (&body enums)
|
||||
"Converts anonymous enums to defconstants."
|
||||
`(cl:progn ,@(cl:loop for value in enums
|
||||
`(cl:progn , @(cl:loop for value in enums
|
||||
for index = 0 then (cl:1+ index)
|
||||
when (cl:listp value) do (cl:setf index (cl:second value)
|
||||
value (cl:first value))
|
||||
collect `(cl:defconstant ,value ,index))))
|
||||
collect `(cl:defconstant , value , index))))
|
||||
|
||||
(cl:eval-when (:compile-toplevel :load-toplevel)
|
||||
(cl:unless (cl:fboundp 'swig-lispify)
|
||||
|
|
@ -281,7 +288,7 @@ Let's edit the interface file such that the C type "div_t*" is changed
|
|||
|
||||
%typemap(cin) div_t* ":my-pointer";
|
||||
|
||||
%feature("intern_function","1");
|
||||
%feature("intern_function", "1");
|
||||
%feature("export");
|
||||
|
||||
%feature("inline") lispsort_double;
|
||||
|
|
@ -306,7 +313,7 @@ The <i>typemap(cin)</i> ensures that for all arguments which are input
|
|||
The feature <i>intern_function</i> ensures that all C names are
|
||||
interned using the <b>swig-lispify</b> function. The "1" given
|
||||
to the feature is optional. The use of feature like
|
||||
<i>%feature("intern_function","1");</i> globally enables
|
||||
<i>%feature("intern_function", "1");</i> globally enables
|
||||
interning for everything. If you want to target a single
|
||||
function, or declaration then use the targeted version of
|
||||
feature, <i>%feature("intern_function", "my-lispify")
|
||||
|
|
@ -431,49 +438,48 @@ 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
|
||||
{
|
||||
{
|
||||
public:
|
||||
float x;
|
||||
// constructors
|
||||
Test (void) {x = 0;}
|
||||
Test (float X) {x = X;}
|
||||
float x;
|
||||
// constructors
|
||||
Test (void) {x = 0;}
|
||||
Test (float X) {x = X;}
|
||||
|
||||
// vector addition
|
||||
Test operator+ (const Test& v) const {return Test (x+v.x);}
|
||||
// vector addition
|
||||
Test operator+ (const Test& v) const {return Test (x+v.x);}
|
||||
|
||||
// length squared
|
||||
float lengthSquared (void) const {return this->dot (*this);}
|
||||
float lengthSquared (void) const {return this->dot (*this);}
|
||||
|
||||
static float distance (const Test& a, const Test& b){return(a-b).length();}
|
||||
static float distance (const Test& a, const Test& b){return(a-b).length();}
|
||||
|
||||
inline Test parallelComponent (const Test& unitBasis) const {
|
||||
return unitBasis * projection;
|
||||
}
|
||||
inline Test parallelComponent (const Test& unitBasis) const {
|
||||
return unitBasis * projection;
|
||||
}
|
||||
|
||||
Test setYtoZero (void) const {return Test (this->x);}
|
||||
Test setYtoZero (void) const {return Test (this->x);}
|
||||
|
||||
static const Test zero;
|
||||
};
|
||||
static const Test zero;
|
||||
};
|
||||
|
||||
inline Test operator* (float s, const Test& v) {return v*s;}
|
||||
|
||||
inline Test operator* (float s, const Test& v) {return v*s;}
|
||||
inline std::ostream& operator<< (std::ostream& o, const Test& v)
|
||||
{
|
||||
return o << "(" << v.x << ")";
|
||||
}
|
||||
|
||||
|
||||
inline std::ostream& operator<< (std::ostream& o, const Test& v)
|
||||
{
|
||||
return o << "(" << v.x << ")";
|
||||
}
|
||||
|
||||
|
||||
inline Test RandomUnitVectorOnXZPlane (void)
|
||||
{
|
||||
return RandomVectorInUnitRadiusSphere().setYtoZero().normalize();
|
||||
}
|
||||
inline Test RandomUnitVectorOnXZPlane (void)
|
||||
{
|
||||
return RandomVectorInUnitRadiusSphere().setYtoZero().normalize();
|
||||
}
|
||||
}
|
||||
</pre></div>
|
||||
<p>The interface used is: </p>
|
||||
|
|
@ -482,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)
|
||||
|
|
@ -532,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>
|
||||
|
|
@ -726,7 +736,7 @@ The ffi wrappers for functions and variables are generated as shown
|
|||
extern "C" {
|
||||
int pointer_func(void (*ClosureFun)( void* _fun, void* _data, void* _evt ), int y);
|
||||
|
||||
int func123(div_t * x,int **z[100],int y[][1000][10]);
|
||||
int func123(div_t * x, int **z[100], int y[][1000][10]);
|
||||
|
||||
void lispsort_double (int n, double * array);
|
||||
|
||||
|
|
@ -778,10 +788,10 @@ The module also handles strutcures and #define constants as shown
|
|||
</p>
|
||||
<div class="code"><pre>
|
||||
struct bar {
|
||||
short x, y;
|
||||
char a, b;
|
||||
int *z[1000];
|
||||
struct bar * n;
|
||||
short x, y;
|
||||
char a, b;
|
||||
int *z[1000];
|
||||
struct bar * n;
|
||||
};
|
||||
|
||||
#define max 1000
|
||||
|
|
|
|||
|
|
@ -193,27 +193,27 @@ Normally Lua is embedded into another program and will be statically linked. An
|
|||
|
||||
extern int luaopen_example(lua_State* L); // declare the wrapped module
|
||||
|
||||
int main(int argc,char* argv[])
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
lua_State *L;
|
||||
if (argc<2)
|
||||
{
|
||||
printf("%s: <filename.lua>\n",argv[0]);
|
||||
printf("%s: <filename.lua>\n", argv[0]);
|
||||
return 0;
|
||||
}
|
||||
L=lua_open();
|
||||
luaopen_base(L); // load basic libs (eg. print)
|
||||
luaopen_example(L); // load the wrapped module
|
||||
if (luaL_loadfile(L,argv[1])==0) // load and run the file
|
||||
lua_pcall(L,0,0,0);
|
||||
if (luaL_loadfile(L, argv[1])==0) // load and run the file
|
||||
lua_pcall(L, 0, 0, 0);
|
||||
else
|
||||
printf("unable to load %s\n",argv[1]);
|
||||
printf("unable to load %s\n", argv[1]);
|
||||
lua_close(L);
|
||||
return 0;
|
||||
}
|
||||
</pre></div>
|
||||
<p>
|
||||
A much improved set of code can be found in the Lua distribution <tt>src/lua/lua.c</tt>. Include your module, just add the external declaration & add a <tt>#define LUA_EXTRALIBS {"example",luaopen_example}</tt>, at the relevant place.
|
||||
A much improved set of code can be found in the Lua distribution <tt>src/lua/lua.c</tt>. Include your module, just add the external declaration & add a <tt>#define LUA_EXTRALIBS {"example", luaopen_example}</tt>, at the relevant place.
|
||||
</p>
|
||||
<p>
|
||||
The exact commands for compiling and linking vary from platform to platform. Here is a possible set of commands of doing this:
|
||||
|
|
@ -272,8 +272,8 @@ require("example")
|
|||
For those using Lua 5.0.x, you will also need an interpreter with the loadlib function (such as the default interpreter compiled with Lua). In order to dynamically load a module you must call the loadlib function with two parameters: the filename of the shared library, and the function exported by SWIG. Calling loadlib should return the function, which you then call to initialise the module
|
||||
</p>
|
||||
<div class="targetlang"><pre>
|
||||
my_init=loadlib("example.so","luaopen_example") -- for Unix/Linux
|
||||
--my_init=loadlib("example.dll","luaopen_example") -- for Windows
|
||||
my_init=loadlib("example.so", "luaopen_example") -- for Unix/Linux
|
||||
--my_init=loadlib("example.dll", "luaopen_example") -- for Windows
|
||||
assert(my_init) -- make sure it's not nil
|
||||
my_init() -- call the init fn of the lib
|
||||
</pre></div>
|
||||
|
|
@ -281,7 +281,7 @@ my_init() -- call the init fn of the lib
|
|||
Or can be done in a single line of Lua code
|
||||
</p>
|
||||
<div class="targetlang"><pre>
|
||||
assert(loadlib("example.so","luaopen_example"))()
|
||||
assert(loadlib("example.so", "luaopen_example"))()
|
||||
</pre></div>
|
||||
|
||||
|
||||
|
|
@ -289,9 +289,9 @@ assert(loadlib("example.so","luaopen_example"))()
|
|||
If the code didn't work, don't panic. The best thing to do is to copy the module and your interpreter into a single directory and then execute the interpreter and try to manually load the module (take care, all this code is case sensitive).
|
||||
</p>
|
||||
<div class="targetlang"><pre>
|
||||
a,b,c=package.loadlib("example.so","luaopen_example") -- for Unix/Linux
|
||||
--a,b,c=package.loadlib("example.dll","luaopen_example") -- for Windows
|
||||
print(a,b,c)
|
||||
a, b, c=package.loadlib("example.so", "luaopen_example") -- for Unix/Linux
|
||||
--a, b, c=package.loadlib("example.dll", "luaopen_example") -- for Windows
|
||||
print(a, b, c)
|
||||
</pre></div>
|
||||
<p>
|
||||
Note: for Lua 5.0:<br>
|
||||
|
|
@ -326,7 +326,7 @@ Assuming all goes well, you will be able to this:
|
|||
</p>
|
||||
<div class="targetlang"><pre>
|
||||
$ ./my_lua
|
||||
> print(example.gcd(4,6))
|
||||
> print(example.gcd(4, 6))
|
||||
2
|
||||
> print(example.Foo)
|
||||
3
|
||||
|
|
@ -373,7 +373,7 @@ This can easily overwrite existing functions, so this must be used with care.
|
|||
This option is considered deprecated and will be removed in the near future.
|
||||
</p>
|
||||
<div class="targetlang"><pre>
|
||||
> for k,v in pairs(example) do _G[k]=v end
|
||||
> for k, v in pairs(example) do _G[k]=v end
|
||||
> print(fact(4))
|
||||
24
|
||||
>
|
||||
|
|
@ -411,7 +411,7 @@ SWIG will effectively generate two functions <tt>example.Foo_set()</tt> and <tt>
|
|||
> print(c)
|
||||
3
|
||||
> c=5 -- this will not effect the original example.Foo
|
||||
> print(example.Foo,c)
|
||||
> print(example.Foo, c)
|
||||
4 5
|
||||
</pre></div>
|
||||
<p>
|
||||
|
|
@ -486,7 +486,7 @@ Because Lua doesn't really have the concept of constants, C/C++ constants are no
|
|||
<div class="code"><pre>%module example
|
||||
%constant int ICONST=42;
|
||||
#define SCONST "Hello World"
|
||||
enum Days{SUNDAY,MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY};
|
||||
enum Days{SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY};
|
||||
</pre></div>
|
||||
<p>
|
||||
This is 'effectively' converted into the following Lua code:
|
||||
|
|
@ -521,9 +521,9 @@ Enums are exported into a class table. For example, given some enums:
|
|||
<div class="code"><pre>%module example
|
||||
enum Days { SUNDAY = 0, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY };
|
||||
struct Test {
|
||||
enum { TEST1 = 10, TEST2 = 20 };
|
||||
enum { TEST1 = 10, TEST2 = 20 };
|
||||
#ifdef __cplusplus // There are no static members in C
|
||||
static const int ICONST = 12;
|
||||
static const int ICONST = 12;
|
||||
#endif
|
||||
};
|
||||
</pre></div>
|
||||
|
|
@ -584,8 +584,8 @@ int fclose(FILE *);
|
|||
When wrapped, you will be able to use the functions in a natural way from Lua. For example:
|
||||
</p>
|
||||
<div class="targetlang"><pre>
|
||||
> f=example.fopen("junk","w")
|
||||
> example.fputs("Hello World",f)
|
||||
> f=example.fopen("junk", "w")
|
||||
> example.fputs("Hello World", f)
|
||||
> example.fclose(f)
|
||||
</pre></div>
|
||||
<p>
|
||||
|
|
@ -601,7 +601,7 @@ FILE * -- it's a FILE*
|
|||
Lua enforces the integrity of its userdata, so it is virtually impossible to corrupt the data. But as the user of the pointer, you are responsible for freeing it, or closing any resources associated with it (just as you would in a C program). This does not apply so strictly to classes & structs (see below). One final note: if a function returns a NULL pointer, this is not encoded as a userdata, but as a Lua nil.
|
||||
</p>
|
||||
<div class="targetlang"><pre>
|
||||
> f=example.fopen("not there","r") -- this will return a NULL in C
|
||||
> f=example.fopen("not there", "r") -- this will return a NULL in C
|
||||
> print(f)
|
||||
nil
|
||||
</pre></div>
|
||||
|
|
@ -613,7 +613,7 @@ nil
|
|||
If you wrap a C structure, it is also mapped to a Lua userdata. By adding a metatable to the userdata, this provides a very natural interface. For example,
|
||||
</p>
|
||||
<div class="code"><pre>struct Point{
|
||||
int x,y;
|
||||
int x, y;
|
||||
};
|
||||
</pre></div>
|
||||
<p>
|
||||
|
|
@ -623,7 +623,7 @@ is used as follows:
|
|||
> p=example.new_Point()
|
||||
> p.x=3
|
||||
> p.y=5
|
||||
> print(p.x,p.y)
|
||||
> print(p.x, p.y)
|
||||
3 5
|
||||
>
|
||||
</pre></div>
|
||||
|
|
@ -645,12 +645,12 @@ Like the pointer in the previous section, this is held as a userdata. However, a
|
|||
<tt>const</tt> members of a structure are read-only. Data members can also be forced to be read-only using the immutable directive. As with other immutables, setting attempts will be cause an error. For example:
|
||||
</p>
|
||||
<div class="code"><pre>struct Foo {
|
||||
...
|
||||
%immutable;
|
||||
int x; // Read-only members
|
||||
char *name;
|
||||
%mutable;
|
||||
...
|
||||
...
|
||||
%immutable;
|
||||
int x; // Read-only members
|
||||
char *name;
|
||||
%mutable;
|
||||
...
|
||||
};
|
||||
</pre></div>
|
||||
<p>
|
||||
|
|
@ -661,11 +661,11 @@ When a member of a structure is itself a structure, it is handled as a pointer.
|
|||
</p>
|
||||
|
||||
<div class="code"><pre>struct Foo {
|
||||
int a;
|
||||
int a;
|
||||
};
|
||||
|
||||
struct Bar {
|
||||
Foo f;
|
||||
Foo f;
|
||||
};
|
||||
</pre></div>
|
||||
<p>
|
||||
|
|
@ -695,8 +695,8 @@ Because the pointer points inside the structure, you can modify the contents and
|
|||
For eLua with the <tt>-eluac</tt> option, structure manipulation has to be performed with specific structure functions generated by SWIG. Let's say you have the following structure definition:
|
||||
</p>
|
||||
<div class="code"><pre>struct data {
|
||||
int x, y;
|
||||
double z;
|
||||
int x, y;
|
||||
double z;
|
||||
};
|
||||
|
||||
> --From eLua
|
||||
|
|
@ -749,8 +749,8 @@ Class data members are accessed in the same manner as C structures. Static class
|
|||
</p>
|
||||
<div class="targetlang"><pre>class Spam {
|
||||
public:
|
||||
static void foo();
|
||||
static int bar;
|
||||
static void foo();
|
||||
static int bar;
|
||||
};
|
||||
</pre></div>
|
||||
<p>
|
||||
|
|
@ -871,9 +871,9 @@ Similarly, if you have a class like this,
|
|||
</p>
|
||||
<div class="code"><pre>class Foo {
|
||||
public:
|
||||
Foo();
|
||||
Foo(const Foo &);
|
||||
...
|
||||
Foo();
|
||||
Foo(const Foo &);
|
||||
...
|
||||
};
|
||||
</pre></div>
|
||||
<p>
|
||||
|
|
@ -953,8 +953,8 @@ public:
|
|||
When wrapped, it works like you expect:
|
||||
</p>
|
||||
<div class="targetlang"><pre>
|
||||
> c = Complex(3,4)
|
||||
> d = Complex(7,8)
|
||||
> c = Complex(3, 4)
|
||||
> d = Complex(7, 8)
|
||||
> e = c + d
|
||||
> e:re()
|
||||
10.0
|
||||
|
|
@ -1000,18 +1000,18 @@ The current list of operators which can be overloaded (and the alternative funct
|
|||
<li><tt>__le__</tt> operator<tt><=</tt>
|
||||
</ul>
|
||||
<p>
|
||||
Note: in Lua, only the equals, less than, and less than equals operators are defined. The other operators (!=,>,>=) are achieved by using a logical not applied to the results of other operators.
|
||||
Note: in Lua, only the equals, less than, and less than equals operators are defined. The other operators (!=, >, >=) are achieved by using a logical not applied to the results of other operators.
|
||||
</p>
|
||||
<p>
|
||||
The following operators cannot be overloaded (mainly because they are not supported in Lua)<ul>
|
||||
<li>++ and --<li>+=,-=,*= etc<li>% operator (you have to use math.mod)<li>assignment operator<li>all bitwise/logical operations</ul>
|
||||
<li>++ and --<li>+=, -=, *= etc<li>% operator (you have to use math.mod)<li>assignment operator<li>all bitwise/logical operations</ul>
|
||||
<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());
|
||||
sprintf(buffer, "Complex(%g, %g)", this->re(), this->im());
|
||||
return buffer;
|
||||
}
|
||||
</pre></div>
|
||||
|
|
@ -1019,14 +1019,14 @@ SWIG also accepts the <tt>__str__()</tt> member function which converts an objec
|
|||
Then this will support the following code in Lua
|
||||
</p>
|
||||
<div class="targetlang"><pre>
|
||||
> c = Complex(3,4)
|
||||
> d = Complex(7,8)
|
||||
> c = Complex(3, 4)
|
||||
> d = Complex(7, 8)
|
||||
> e = c + d
|
||||
> print(e)
|
||||
Complex(10,12)
|
||||
Complex(10, 12)
|
||||
> s=tostring(e) -- s is the number in string form
|
||||
> print(s)
|
||||
Complex(10,12)
|
||||
Complex(10, 12)
|
||||
</pre></div>
|
||||
<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>
|
||||
|
|
@ -1035,7 +1035,7 @@ It is also possible to overload the operator<tt>[]</tt>, but currently this cann
|
|||
{
|
||||
//....
|
||||
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
|
||||
void __setitem__(int i, double d); // i is the index, d is the data
|
||||
};
|
||||
</pre></div>
|
||||
<p>
|
||||
|
|
@ -1090,27 +1090,28 @@ public:
|
|||
Now we extend it with some new code
|
||||
</p>
|
||||
<div class="code"><pre>%extend Complex {
|
||||
const char *__str__() {
|
||||
static char tmp[1024];
|
||||
sprintf(tmp,"Complex(%g,%g)", $self->re(),$self->im());
|
||||
return tmp;
|
||||
}
|
||||
bool operator==(const Complex& c)
|
||||
{ return ($self->re()==c.re() && $self->im()==c.im());}
|
||||
const char *__str__() {
|
||||
static char tmp[1024];
|
||||
sprintf(tmp, "Complex(%g, %g)", $self->re(), $self->im());
|
||||
return tmp;
|
||||
}
|
||||
bool operator==(const Complex& c) {
|
||||
return ($self->re()==c.re() && $self->im()==c.im());
|
||||
}
|
||||
};
|
||||
</pre></div>
|
||||
<p>
|
||||
Now, in Lua
|
||||
</p>
|
||||
<div class="targetlang"><pre>
|
||||
> c = Complex(3,4)
|
||||
> d = Complex(7,8)
|
||||
> c = Complex(3, 4)
|
||||
> d = Complex(7, 8)
|
||||
> e = c + d
|
||||
> print(e) -- print uses __str__ to get the string form to print
|
||||
Complex(10,12)
|
||||
> print(e==Complex(10,12)) -- testing the == operator
|
||||
Complex(10, 12)
|
||||
> print(e==Complex(10, 12)) -- testing the == operator
|
||||
true
|
||||
> print(e!=Complex(12,12)) -- the != uses the == operator
|
||||
> print(e!=Complex(12, 12)) -- the != uses the == operator
|
||||
true
|
||||
</pre></div>
|
||||
<p>
|
||||
|
|
@ -1123,9 +1124,9 @@ Extend works with both C and C++ code, on classes and structs. It does not modif
|
|||
<p> If you have a function that allocates memory like this,</p>
|
||||
<div class="code">
|
||||
<pre>char *foo() {
|
||||
char *result = (char *) malloc(...);
|
||||
...
|
||||
return result;
|
||||
char *result = (char *) malloc(...);
|
||||
...
|
||||
return result;
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1154,23 +1155,23 @@ char *foo();
|
|||
|
||||
template<class T1, class T2>
|
||||
struct pair {
|
||||
typedef T1 first_type;
|
||||
typedef T2 second_type;
|
||||
T1 first;
|
||||
T2 second;
|
||||
pair();
|
||||
pair(const T1&, const T2&);
|
||||
typedef T1 first_type;
|
||||
typedef T2 second_type;
|
||||
T1 first;
|
||||
T2 second;
|
||||
pair();
|
||||
pair(const T1&, const T2&);
|
||||
~pair();
|
||||
};
|
||||
|
||||
%template(pairii) pair<int,int>;
|
||||
%template(pairii) pair<int, int>;
|
||||
</pre></div>
|
||||
<p>
|
||||
In Lua:
|
||||
</p>
|
||||
<div class="targetlang"><pre>
|
||||
> p = example.pairii(3,4)
|
||||
> print(p.first,p.second)
|
||||
> p = example.pairii(3, 4)
|
||||
> print(p.first, p.second)
|
||||
3 4
|
||||
</pre></div>
|
||||
<p>
|
||||
|
|
@ -1183,9 +1184,9 @@ Obviously, there is more to template wrapping than shown in this example. More d
|
|||
In certain C++ programs, it is common to use classes that have been wrapped by so-called "smart pointers." Generally, this involves the use of a template class that implements operator->() like this:
|
||||
</p>
|
||||
<div class="code"><pre>template<class T> class SmartPtr {
|
||||
...
|
||||
T *operator->();
|
||||
...
|
||||
...
|
||||
T *operator->();
|
||||
...
|
||||
}
|
||||
</pre></div>
|
||||
<p>
|
||||
|
|
@ -1193,8 +1194,8 @@ Then, if you have a class like this,
|
|||
</p>
|
||||
<div class="code"><pre>class Foo {
|
||||
public:
|
||||
int x;
|
||||
int bar();
|
||||
int x;
|
||||
int bar();
|
||||
};
|
||||
</pre></div>
|
||||
<p>
|
||||
|
|
@ -1264,11 +1265,11 @@ Using xpcall will allow you to obtain additional debug information (such as a st
|
|||
<div class="targetlang"><pre>
|
||||
> function a() b() end -- function a() calls function b()
|
||||
> function b() message() end -- function b() calls C++ function message(), which throws
|
||||
> ok,res=pcall(a) -- call the function
|
||||
> print(ok,res)
|
||||
> ok, res=pcall(a) -- call the function
|
||||
> print(ok, res)
|
||||
false I died.
|
||||
> ok,res=xpcall(a,debug.traceback) -- call the function
|
||||
> print(ok,res)
|
||||
> ok, res=xpcall(a, debug.traceback) -- call the function
|
||||
> print(ok, res)
|
||||
false I died.
|
||||
stack traceback:
|
||||
[C]: in function 'message'
|
||||
|
|
@ -1321,7 +1322,7 @@ If you have your own class which you want output as a string you will need to ad
|
|||
<div class="code"><pre>
|
||||
%typemap(throws) my_except
|
||||
%{
|
||||
lua_pushstring(L,$1.what()); // assuming my_except::what() returns a const char* message
|
||||
lua_pushstring(L, $1.what()); // assuming my_except::what() returns a const char* message
|
||||
SWIG_fail; // trigger the error handler
|
||||
%}
|
||||
</pre></div>
|
||||
|
|
@ -1336,26 +1337,26 @@ class Exc {
|
|||
public:
|
||||
Exc(int c, const char *m) {
|
||||
code = c;
|
||||
strncpy(msg,m,256);
|
||||
strncpy(msg, m, 256);
|
||||
}
|
||||
int code;
|
||||
char msg[256];
|
||||
};
|
||||
|
||||
void throw_exc() throw(Exc) {
|
||||
throw(Exc(42,"Hosed"));
|
||||
throw(Exc(42, "Hosed"));
|
||||
}
|
||||
</pre></div>
|
||||
<p>
|
||||
Then the following code can be used (note: we use pcall to catch the error so we can process the exception).
|
||||
</p>
|
||||
<div class="targetlang"><pre>
|
||||
> ok,res=pcall(throw_exc)
|
||||
> ok, res=pcall(throw_exc)
|
||||
> print(ok)
|
||||
false
|
||||
> print(res)
|
||||
userdata: 0003D880
|
||||
> print(res.code,res.msg)
|
||||
> print(res.code, res.msg)
|
||||
42 Hosed
|
||||
>
|
||||
</pre></div>
|
||||
|
|
@ -1536,8 +1537,8 @@ function
|
|||
<div class="code"><pre>%module example
|
||||
|
||||
%typemap(in) int {
|
||||
$1 = (int) lua_tonumber(L,$input);
|
||||
printf("Received an integer : %d\n",$1);
|
||||
$1 = (int) lua_tonumber(L, $input);
|
||||
printf("Received an integer : %d\n", $1);
|
||||
}
|
||||
%inline %{
|
||||
extern int fact(int n);
|
||||
|
|
@ -1564,17 +1565,17 @@ Received an integer : 6
|
|||
<p>However for more complex functions which use input/output parameters or arrays, you will need to make use of <typemaps.i>, which contains typemaps for these situations. For example, consider these functions:</p>
|
||||
|
||||
<div class="code"><pre>void add(int x, int y, int *result) {
|
||||
*result = x + y;
|
||||
*result = x + y;
|
||||
}
|
||||
|
||||
int sub(int *x1, int *y1) {
|
||||
return *x1-*y1;
|
||||
return *x1-*y1;
|
||||
}
|
||||
|
||||
void swap(int *sx, int *sy) {
|
||||
int t=*sx;
|
||||
*sx=*sy;
|
||||
*sy=t;
|
||||
int t=*sx;
|
||||
*sx=*sy;
|
||||
*sy=t;
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -1595,13 +1596,13 @@ void swap(int *sx, int *sy);
|
|||
<p>When wrapped, it gives the following results:</p>
|
||||
|
||||
<div class="targetlang"><pre>> require "example"
|
||||
> print(example.add(1,2))
|
||||
> print(example.add(1, 2))
|
||||
3
|
||||
> print(demo.sub(1,2))
|
||||
> print(demo.sub(1, 2))
|
||||
-1
|
||||
> a,b=1,2
|
||||
> c,d=demo.swap(a,b)
|
||||
> print(a,b,c,d)
|
||||
> a, b=1, 2
|
||||
> c, d=demo.swap(a, b)
|
||||
> print(a, b, c, d)
|
||||
1 2 2 1
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -1632,13 +1633,13 @@ More details can be found in the <a href="Library.html#Library_carrays">carrays.
|
|||
<div class="code"><pre>// using the C-array
|
||||
%include <carrays.i>
|
||||
// this declares a batch of function for manipulating C integer arrays
|
||||
%array_functions(int,int)
|
||||
%array_functions(int, int)
|
||||
|
||||
extern void sort_int(int* arr, int len); // the function to wrap
|
||||
|
||||
// using typemaps
|
||||
%include <typemaps.i>
|
||||
%apply (double *INOUT,int) {(double* arr,int len)};
|
||||
%apply (double *INOUT, int) {(double* arr, int len)};
|
||||
|
||||
extern void sort_double(double* arr, int len); // the function to wrap
|
||||
</pre></div>
|
||||
|
|
@ -1650,16 +1651,16 @@ ARRAY_SIZE=10
|
|||
|
||||
-- passing a C array to the sort_int()
|
||||
arr=example.new_int(ARRAY_SIZE) -- create the array
|
||||
for i=0,ARRAY_SIZE-1 do -- index 0..9 (just like C)
|
||||
example.int_setitem(arr,i,math.random(1000))
|
||||
for i=0, ARRAY_SIZE-1 do -- index 0..9 (just like C)
|
||||
example.int_setitem(arr, i, math.random(1000))
|
||||
end
|
||||
example.sort_int(arr,ARRAY_SIZE) -- call the function
|
||||
example.sort_int(arr, ARRAY_SIZE) -- call the function
|
||||
example.delete_int(arr) -- must delete the allocated memory
|
||||
|
||||
-- use a typemap to call with a Lua-table
|
||||
-- one item of note: the typemap creates a copy, rather than edit-in-place
|
||||
t={} -- a Lua table
|
||||
for i=1,ARRAY_SIZE do -- index 1..10 (Lua style)
|
||||
for i=1, ARRAY_SIZE do -- index 1..10 (Lua style)
|
||||
t[i]=math.random(1000)/10
|
||||
end
|
||||
t=example.sort_double(t) -- replace t with the result
|
||||
|
|
@ -1703,7 +1704,7 @@ int Create_Math(iMath** pptr); // its creator (assume it mallocs)
|
|||
|
||||
<p>The usage is as follows:</p>
|
||||
|
||||
<div class="targetlang"><pre>ok,ptr=Create_Math() -- ptr is an iMath* which is returned with the int (ok)
|
||||
<div class="targetlang"><pre>ok, ptr=Create_Math() -- ptr is an iMath* which is returned with the int (ok)
|
||||
ptr=nil -- the iMath* will be GC'ed as normal
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -1734,22 +1735,22 @@ ptr=nil -- the iMath* will be GC'ed as normal
|
|||
|
||||
<p>This section explains the SWIG specific Lua-C API. It does not cover the main Lua-C api, as this is well documented and not worth covering.</p>
|
||||
|
||||
<p><tt>int SWIG_ConvertPtr(lua_State* L,int index,void** ptr,swig_type_info *type,int flags);</tt></p>
|
||||
<p><tt>int SWIG_ConvertPtr(lua_State* L, int index, void** ptr, swig_type_info *type, int flags);</tt></p>
|
||||
|
||||
<div class="indent">
|
||||
This is the standard function used for converting a Lua userdata to a void*. It takes the value at the given index in the Lua state and converts it to a userdata. It will then provide the necessary type checks, confirming that the pointer is compatible with the type given in 'type'. Then finally setting '*ptr' to the pointer.
|
||||
If flags is set to SWIG_POINTER_DISOWN, this is will clear any ownership flag set on the object.<br>
|
||||
The returns a value which can be checked with the macro SWIG_IsOK()
|
||||
This returns a value which can be checked with the macro SWIG_IsOK()
|
||||
</div>
|
||||
|
||||
<p><tt>void SWIG_NewPointerObj(lua_State* L,void* ptr,swig_type_info *type,int own);</tt></p>
|
||||
<p><tt>void SWIG_NewPointerObj(lua_State* L, void* ptr, swig_type_info *type, int own);</tt></p>
|
||||
|
||||
<div class="indent">
|
||||
This is the opposite of SWIG_ConvertPtr, as it pushes a new userdata which wrappers the pointer 'ptr' of type 'type'.
|
||||
The parameter 'own' specifies if the object is owned be Lua and if it is 1 then Lua will GC the object when the userdata is disposed of.
|
||||
</div>
|
||||
|
||||
<p><tt>void* SWIG_MustGetPtr(lua_State* L,int index,swig_type_info *type,int flags,int argnum,const char* func_name);</tt></p>
|
||||
<p><tt>void* SWIG_MustGetPtr(lua_State* L, int index, swig_type_info *type, int flags, int argnum, const char* func_name);</tt></p>
|
||||
|
||||
<div class="indent">
|
||||
This function is a version of SWIG_ConvertPtr(), except that it will either work, or it will trigger a lua_error() with a text error message. This function is rarely used, and may be deprecated in the future.
|
||||
|
|
@ -1761,11 +1762,11 @@ This function is a version of SWIG_ConvertPtr(), except that it will either work
|
|||
This macro, when called within the context of a SWIG wrapped function, will jump to the error handler code. This will call any cleanup code (freeing any temp variables) and then triggers a lua_error.<br>
|
||||
A common use for this code is:<br><pre>
|
||||
if (!SWIG_IsOK(SWIG_ConvertPtr( .....)){
|
||||
lua_pushstring(L,"something bad happened");
|
||||
lua_pushstring(L, "something bad happened");
|
||||
SWIG_fail;
|
||||
}</pre></div>
|
||||
|
||||
<p><tt>SWIG_fail_arg(char* func_name,int argnum,char* type)</tt></p>
|
||||
<p><tt>SWIG_fail_arg(char* func_name, int argnum, char* type)</tt></p>
|
||||
|
||||
<div class="indent">
|
||||
This macro, when called within the context of a SWIG wrapped function, will display the error message and jump to the error handler code. The error message is of the form
|
||||
|
|
@ -1773,7 +1774,7 @@ This macro, when called within the context of a SWIG wrapped function, will disp
|
|||
"Error in <i>func_name</i> (arg <i>argnum</i>), expected '<i>type</i>' got '<i>whatever the type was</i>'"
|
||||
</pre></div>
|
||||
|
||||
<p><tt>SWIG_fail_ptr(const char* fn_name,int argnum,swig_type_info* type);</tt></p>
|
||||
<p><tt>SWIG_fail_ptr(const char* fn_name, int argnum, swig_type_info* type);</tt></p>
|
||||
|
||||
<div class="indent">
|
||||
Similar to SWIG_fail_arg, except that it will display the swig_type_info information instead.</div>
|
||||
|
|
@ -1877,24 +1878,24 @@ At initialisation time, it will then add to the interpreter a table called 'exam
|
|||
> print(example)
|
||||
table: 003F8F90
|
||||
> m=getmetatable(example)
|
||||
> table.foreach(m,print)
|
||||
> table.foreach(m, print)
|
||||
.set table: 003F9088
|
||||
.get table: 003F9038
|
||||
__index function: 003F8FE0
|
||||
__newindex function: 003F8FF8
|
||||
> g=m['.get']
|
||||
> table.foreach(g,print)
|
||||
> table.foreach(g, print)
|
||||
Foo function: 003FAFD8
|
||||
>
|
||||
</pre></div>
|
||||
<p>
|
||||
The .get and .set tables are lookups connecting the variable name 'Foo' to the accessor/mutator functions (Foo_set,Foo_get)
|
||||
The .get and .set tables are lookups connecting the variable name 'Foo' to the accessor/mutator functions (Foo_set, Foo_get)
|
||||
</p>
|
||||
<p>
|
||||
The Lua equivalent of the code for the <tt>__index</tt> and <tt>__newindex</tt> looks a bit like this
|
||||
</p>
|
||||
<div class="targetlang"><pre>
|
||||
function __index(mod,name)
|
||||
function __index(mod, name)
|
||||
local g=getmetatable(mod)['.get'] -- gets the table
|
||||
if not g then return nil end
|
||||
local f=g[name] -- looks for the function
|
||||
|
|
@ -1903,13 +1904,13 @@ function __index(mod,name)
|
|||
return nil
|
||||
end
|
||||
|
||||
function __newindex(mod,name,value)
|
||||
function __newindex(mod, name, value)
|
||||
local s=getmetatable(mod)['.set'] -- gets the table
|
||||
if not s then return end
|
||||
local f=s[name] -- looks for the function
|
||||
-- calls it to set the value
|
||||
if type(f)=="function" then f(value)
|
||||
else rawset(mod,name,value) end
|
||||
else rawset(mod, name, value) end
|
||||
end
|
||||
</pre></div>
|
||||
<p>
|
||||
|
|
@ -1932,10 +1933,10 @@ Given a class
|
|||
class Point
|
||||
{
|
||||
public:
|
||||
int x,y;
|
||||
int x, y;
|
||||
Point(){x=y=0;}
|
||||
~Point(){}
|
||||
virtual void Print(){printf("Point @%p (%d,%d)\n",this,x,y);}
|
||||
virtual void Print(){printf("Point @%p (%d, %d)\n", this, x, y);}
|
||||
};
|
||||
</pre></div>
|
||||
<p>
|
||||
|
|
@ -1949,7 +1950,7 @@ Some of the internals can be seen by looking at the metatable of a class:
|
|||
> print(p)
|
||||
userdata: 003FDB28
|
||||
> m=getmetatable(p)
|
||||
> table.foreach(m,print)
|
||||
> table.foreach(m, print)
|
||||
.type Point
|
||||
__gc function: 003FB6C8
|
||||
__newindex function: 003FB6B0
|
||||
|
|
@ -1965,7 +1966,7 @@ The '.type' attribute is the name of the class. The '.get' and '.set' tables wor
|
|||
The Lua equivalent of the code for enabling functions looks a little like this
|
||||
</p>
|
||||
<div class="targetlang"><pre>
|
||||
function __index(obj,name)
|
||||
function __index(obj, name)
|
||||
local m=getmetatable(obj) -- gets the metatable
|
||||
if not m then return nil end
|
||||
local g=m['.get'] -- gets the attribute table
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
# Makefile for generating the SWIG documentation
|
||||
#
|
||||
# Note that the htmldoc package needs to be installed, but requires patching (using the
|
||||
# margin-left.patch file from this directory) in order to correctly generate the pdf docs.
|
||||
# Note that the htmldoc package needs to be installed. wkhtmltopdf patched with qt is also required
|
||||
# and can be installed from http://wkhtmltopdf.org/downloads.html.
|
||||
#
|
||||
# The .html files are first processed and updated with chapter numbering and anchor names
|
||||
# are added to the HTML headings using the python scripts. The htmldoc program is then
|
||||
# used to generate the PDF document and single page HTML version of the documentation.
|
||||
# used to generate the single page HTML version of the documentation.
|
||||
# wkhtmltopdf is used to generate the pdf document from the single page html file.
|
||||
# HTML TIDY (package also known as tidy) is also required and is used as an aid to HTML
|
||||
# validation.
|
||||
#
|
||||
|
|
|
|||
|
|
@ -684,7 +684,7 @@ consist of the following parts:
|
|||
</tr>
|
||||
<tr>
|
||||
<td>m3wrapfreearg</td>
|
||||
<td><tt>M3toC.FreeSharedS(str,arg1);</tt></td>
|
||||
<td><tt>M3toC.FreeSharedS(str, arg1);</tt></td>
|
||||
<td>
|
||||
Free resources that were temporarily used in the wrapper.
|
||||
Since this step should never be skipped,
|
||||
|
|
@ -858,7 +858,7 @@ where almost everything is generated by a typemap:
|
|||
RAISE E("invalid checksum");
|
||||
END;
|
||||
FINALLY
|
||||
M3toC.FreeSharedS(str,arg1); <I>(* m3wrapfreearg *)</I>
|
||||
M3toC.FreeSharedS(str, arg1); <I>(* m3wrapfreearg *)</I>
|
||||
END;
|
||||
END Name;
|
||||
</pre></div>
|
||||
|
|
@ -891,7 +891,7 @@ where almost everything is generated by a typemap:
|
|||
<tr>
|
||||
<td>constnumeric</td>
|
||||
<td><tt>%constnumeric(12) twelve;</tt> or
|
||||
<tt>%feature("constnumeric","12") twelve;</tt></td>
|
||||
<tt>%feature("constnumeric", "12") twelve;</tt></td>
|
||||
<td>This feature can be used to tell Modula-3's back-end of SWIG
|
||||
the value of an identifier.
|
||||
This is necessary in the cases
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ The general form of this directive is:
|
|||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
<tt>%module(option1="value1",option2="value2",...) modulename</tt>
|
||||
<tt>%module(option1="value1", option2="value2", ...) modulename</tt>
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
|
|
|
|||
|
|
@ -34,14 +34,14 @@ Example interface file:
|
|||
<div class="code">
|
||||
<pre>
|
||||
/* define a macro for the struct creation */
|
||||
%define handle_ptr(TYPE,NAME)
|
||||
%define handle_ptr(TYPE, NAME)
|
||||
%typemap(argout) TYPE *NAME{
|
||||
Scheme_Object *o = SWIG_NewStructFromPtr($1, $*1_mangle);
|
||||
SWIG_APPEND_VALUE(o);
|
||||
Scheme_Object *o = SWIG_NewStructFromPtr($1, $*1_mangle);
|
||||
SWIG_APPEND_VALUE(o);
|
||||
}
|
||||
|
||||
%typemap(in,numinputs=0) TYPE *NAME (TYPE temp) {
|
||||
$1 = &temp;
|
||||
%typemap(in, numinputs=0) TYPE *NAME (TYPE temp) {
|
||||
$1 = &temp;
|
||||
}
|
||||
%enddef
|
||||
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ If you're not familiar with the Objective Caml language, you can visit
|
|||
<p>
|
||||
SWIG 3.0 works with Ocaml 3.08.3 and above. Given the choice,
|
||||
you should use the latest stable release. The SWIG Ocaml module has
|
||||
been tested on Linux (x86,PPC,Sparc) and Cygwin on Windows. The
|
||||
been tested on Linux (x86, PPC, Sparc) and Cygwin on Windows. The
|
||||
best way to determine whether your system will work is to compile the
|
||||
examples and test-suite which come with SWIG. You can do this by running
|
||||
<tt>make check</tt> from the SWIG root directory after installing SWIG.
|
||||
|
|
@ -327,7 +327,7 @@ A few functions exist which generate and return these:
|
|||
Because of this style, a typemap can return any kind of value it
|
||||
wants from a function. This enables out typemaps and inout typemaps
|
||||
to work well. The one thing to remember about outputting values
|
||||
is that you must append them to the return list with swig_result = caml_list_append(swig_result,v).
|
||||
is that you must append them to the return list with swig_result = caml_list_append(swig_result, v).
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
|
@ -505,7 +505,7 @@ Unfortunately, unbounded arrays and pointers can't be handled in a
|
|||
completely general way by SWIG, because the end-condition of such an
|
||||
array can't be predicted. In some cases, it will be by consent
|
||||
(e.g. an array of four or more chars), sometimes by explicit length
|
||||
(char *buffer, int len), and sometimes by sentinel value (0,-1,etc.).
|
||||
(char *buffer, int len), and sometimes by sentinel value (0, -1, etc.).
|
||||
SWIG can't predict which of these methods will be used in the array,
|
||||
so you have to specify it for yourself in the form of a typemap.
|
||||
</p>
|
||||
|
|
@ -560,7 +560,7 @@ void printfloats( float *tab, int len ) {
|
|||
$2 = caml_array_len($input);
|
||||
$1 = ($*1_type *)malloc( $2 * sizeof( float ) );
|
||||
for( i = 0; i < $2; i++ ) {
|
||||
$1[i] = caml_double_val(caml_array_nth($input,i));
|
||||
$1[i] = caml_double_val(caml_array_nth($input, i));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -684,7 +684,7 @@ C_list
|
|||
- : Example.c_obj = C_void
|
||||
# x '[1] ;;
|
||||
- : Example.c_obj = C_string "bar"
|
||||
# x -> set (1,"spam") ;;
|
||||
# x -> set (1, "spam") ;;
|
||||
- : Example.c_obj = C_void
|
||||
# x '[1] ;;
|
||||
- : Example.c_obj = C_string "spam"
|
||||
|
|
@ -757,11 +757,11 @@ bash-2.05a$ ./qt_top
|
|||
|
||||
# open Swig ;;
|
||||
# open Qt ;;
|
||||
# let a = new_QApplication '(0,0) ;;
|
||||
# let a = new_QApplication '(0, 0) ;;
|
||||
val a : Qt.c_obj = C_obj <fun>
|
||||
# let hello = new_QPushButton '("hi",0) ;;
|
||||
# let hello = new_QPushButton '("hi", 0) ;;
|
||||
val hello : Qt.c_obj = C_obj <fun>
|
||||
# hello -> resize (100,30) ;;
|
||||
# hello -> resize (100, 30) ;;
|
||||
- : Qt.c_obj = C_void
|
||||
# hello -> show () ;;
|
||||
- : Qt.c_obj = C_void
|
||||
|
|
@ -857,7 +857,7 @@ let triangle_class pts ob meth args =
|
|||
let triangle =
|
||||
new_derived_object
|
||||
new_shape
|
||||
(triangle_class ((0.0,0.0),(0.5,1.0),(1.0,0.0)))
|
||||
(triangle_class ((0.0, 0.0), (0.5, 1.0), (1.0, 0.0)))
|
||||
'() ;;
|
||||
|
||||
let _ = _draw_shape_coverage '(triangle, C_int 60, C_int 20) ;;
|
||||
|
|
@ -901,7 +901,7 @@ The definition of the actual object triangle can be described this way:
|
|||
let triangle =
|
||||
new_derived_object
|
||||
new_shape
|
||||
(triangle_class ((0.0,0.0),(0.5,1.0),(1.0,0.0)))
|
||||
(triangle_class ((0.0, 0.0), (0.5, 1.0), (1.0, 0.0)))
|
||||
'()
|
||||
</pre></div>
|
||||
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ More information can be found at <a href="http://www.gnu.org/software/octave/">O
|
|||
</p>
|
||||
|
||||
<p>
|
||||
This chapter is intended to give an introduction to using the module. You should also read the SWIG documentation that is not specific to Octave.
|
||||
This chapter is intended to give an introduction to using the module. You should also read the SWIG documentation that is not specific to Octave.
|
||||
Also, there are a dozen or so examples in the Examples/octave directory, and hundreds in the test suite (Examples/test-suite and Examples/test-suite/octave).
|
||||
</p>
|
||||
|
||||
|
|
@ -64,8 +64,15 @@ Also, there are a dozen or so examples in the Examples/octave directory, and hun
|
|||
|
||||
|
||||
<p>
|
||||
As of SWIG 3.0.7, the Octave module is regularly tested with Octave versions 3.2.4, 3.8.1, and 4.0.0.
|
||||
Use of older Octave versions is not recommended, as these versions are no longer tested with SWIG.
|
||||
SWIG is regularly tested against the following versions of Octave: 3.8, 4.0, 4.2.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Every effort is made to maintain backward compatibility with older versions of Octave.
|
||||
This cannot be guaranteed however, as in recent times new Octave releases have required nontrivial updates to SWIG, which may break backward compatibility for older Octave versions against which SWIG is not regularly tested.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The SWIG runtime exports the function <tt>swig_octave_prereq()</tt> for checking the version of Octave.
|
||||
</p>
|
||||
|
||||
|
|
@ -161,7 +168,7 @@ Assuming all goes well, you will be able to do this:
|
|||
|
||||
<div class="targetlang"><pre>$ octave -q
|
||||
octave:1> swigexample
|
||||
octave:2> swigexample.gcd(4,6)
|
||||
octave:2> swigexample.gcd(4, 6)
|
||||
ans = 2
|
||||
octave:3> swigexample.cvar.Foo
|
||||
ans = 3
|
||||
|
|
@ -189,7 +196,7 @@ To load an Octave module, simply type its name:
|
|||
|
||||
<div class="targetlang"><pre>
|
||||
octave:1> swigexample;
|
||||
octave:2> gcd(4,6)
|
||||
octave:2> gcd(4, 6)
|
||||
ans = 2
|
||||
octave:3> cvar.Foo
|
||||
ans = 3
|
||||
|
|
@ -204,16 +211,16 @@ If the module is also used in the base context, however, it must first be loaded
|
|||
</p>
|
||||
|
||||
<div class="targetlang"><pre>
|
||||
octave:1> function l = my_lcm(a,b)
|
||||
octave:1> function l = my_lcm(a, b)
|
||||
> swigexample
|
||||
> l = abs(a*b)/swigexample.gcd(a,b);
|
||||
> l = abs(a*b)/swigexample.gcd(a, b);
|
||||
> endfunction
|
||||
octave:2> my_lcm(4,6)
|
||||
octave:2> my_lcm(4, 6)
|
||||
ans = 12
|
||||
octave:3> swigexample.gcd(4,6)
|
||||
octave:3> swigexample.gcd(4, 6)
|
||||
error: can't perform indexing operations for <unknown type> type
|
||||
octave:3> swigexample;
|
||||
octave:4> swigexample.gcd(4,6)
|
||||
octave:4> swigexample.gcd(4, 6)
|
||||
ans = 2
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -297,7 +304,7 @@ ans = 3.1420 </pre></div>
|
|||
<div class="code"><pre>%module swigexample
|
||||
%constant int ICONST=42;
|
||||
#define SCONST "Hello World"
|
||||
enum Days{SUNDAY,MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY};
|
||||
enum Days{SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY};
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
|
|
@ -314,7 +321,7 @@ swigexample.SUNDAY=0
|
|||
|
||||
<p>
|
||||
C/C++ pointers are fully supported by SWIG. Furthermore, SWIG has no problem working with incomplete type information. Given a wrapping of the <file.h> interface:
|
||||
C/C++ pointers are fully supported by SWIG. Furthermore, SWIG has no problem working with incomplete type information. Given a wrapping of the <file.h> interface:
|
||||
C/C++ pointers are fully supported by SWIG. Furthermore, SWIG has no problem working with incomplete type information. Given a wrapping of the <file.h> interface:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>%module swigexample
|
||||
|
|
@ -329,8 +336,8 @@ When wrapped, you will be able to use the functions in a natural way from Octave
|
|||
|
||||
<div class="targetlang"><pre>
|
||||
octave:1> swigexample;
|
||||
octave:2> f=swigexample.fopen("w","junk");
|
||||
octave:3> swigexample.fputs("Hello world",f);
|
||||
octave:2> f=swigexample.fopen("w", "junk");
|
||||
octave:3> swigexample.fputs("Hello world", f);
|
||||
octave:4> swigexample.fclose(f);
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -339,7 +346,7 @@ octave:4> swigexample.fclose(f);
|
|||
</p>
|
||||
|
||||
<div class="targetlang"><pre>octave:1> swigexample;
|
||||
octave:2> f=swigexample.fopen("junk","w");
|
||||
octave:2> f=swigexample.fopen("junk", "w");
|
||||
octave:3> f
|
||||
f =
|
||||
|
||||
|
|
@ -352,7 +359,7 @@ f =
|
|||
</p>
|
||||
|
||||
<div class="targetlang"><pre>octave:1> swigexample;
|
||||
octave:2> f=swigexample.fopen("not there","r");
|
||||
octave:2> f=swigexample.fopen("not there", "r");
|
||||
error: value on right hand side of assignment is undefined
|
||||
error: evaluating assignment expression near line 2, column 2 </pre></div>
|
||||
|
||||
|
|
@ -365,7 +372,7 @@ For each wrapped structure and class, a <tt>swig_ref</tt> will be exposed that h
|
|||
</p>
|
||||
|
||||
<div class="code"><pre>struct Point{
|
||||
int x,y;
|
||||
int x, y;
|
||||
};
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -395,12 +402,12 @@ Methods also work as expected. For example, code wrapped in the following way
|
|||
|
||||
<div class="code"><pre>class Point{
|
||||
public:
|
||||
int x,y;
|
||||
Point(int _x,int _y) : x(_x),y(_y) {}
|
||||
int x, y;
|
||||
Point(int _x, int _y) : x(_x), y(_y) {}
|
||||
double distance(const Point& rhs) {
|
||||
return sqrt(pow(x-rhs.x,2)+pow(y-rhs.y,2));
|
||||
return sqrt(pow(x-rhs.x, 2)+pow(y-rhs.y, 2));
|
||||
}
|
||||
void set(int _x,int _y) {
|
||||
void set(int _x, int _y) {
|
||||
x=_x; y=_y;
|
||||
}
|
||||
};
|
||||
|
|
@ -410,8 +417,8 @@ can be used from Octave like this
|
|||
</p>
|
||||
<div class="targetlang">
|
||||
<pre>octave:1> swigexample;
|
||||
octave:2> p1=swigexample.Point(3,5);
|
||||
octave:3> p2=swigexample.Point(1,2);
|
||||
octave:2> p1=swigexample.Point(3, 5);
|
||||
octave:3> p2=swigexample.Point(1, 2);
|
||||
octave:4> p1.distance(p2)
|
||||
ans = 3.6056
|
||||
</pre></div>
|
||||
|
|
@ -433,7 +440,7 @@ This differs from the usual pass-by-value (copy-on-write) semantics that Octave
|
|||
|
||||
<div class="targetlang">
|
||||
<pre>
|
||||
octave:7> a=struct('x',4)
|
||||
octave:7> a=struct('x', 4)
|
||||
a =
|
||||
{
|
||||
x = 4
|
||||
|
|
@ -464,7 +471,7 @@ However, when dealing with wrapped objects, one gets the behavior
|
|||
|
||||
<div class="targetlang">
|
||||
<pre>
|
||||
octave:2> a=Point(3,5)
|
||||
octave:2> a=Point(3, 5)
|
||||
a =
|
||||
|
||||
{
|
||||
|
|
@ -478,7 +485,7 @@ b =
|
|||
Point, ptr = 0x9afbbb0
|
||||
}
|
||||
|
||||
octave:4> b.set(2,1);
|
||||
octave:4> b.set(2, 1);
|
||||
octave:5> b.x, b.y
|
||||
ans = 2
|
||||
ans = 1
|
||||
|
|
@ -621,7 +628,7 @@ Octave can also utilise friend (i.e. non-member) operators with a simple %rename
|
|||
The %extend directive works the same as in other modules.
|
||||
</p>
|
||||
<p>
|
||||
You can use it to define special behavior, like for example defining Octave operators not mapped to C++ operators, or defining certain Octave mechanisms such as how an object prints. For example, the <tt>octave_value::{is_string,string_value,print}</tt> functions are routed to a special method <tt>__str__</tt> that can be defined inside an %extend.
|
||||
You can use it to define special behavior, like for example defining Octave operators not mapped to C++ operators, or defining certain Octave mechanisms such as how an object prints. For example, the <tt>octave_value::{is_string, string_value, print}</tt> functions are routed to a special method <tt>__str__</tt> that can be defined inside an %extend.
|
||||
</p>
|
||||
<div class="code"><pre>
|
||||
%extend A {
|
||||
|
|
@ -639,7 +646,7 @@ Then in Octave one gets,
|
|||
octave:1> a=A(4);
|
||||
octave:2> a
|
||||
a = 4
|
||||
octave:3> printf("%s\n",a);
|
||||
octave:3> printf("%s\n", a);
|
||||
4
|
||||
octave:4> a.__str__()
|
||||
4
|
||||
|
|
@ -663,10 +670,10 @@ For example, function templates can be instantiated as follows:
|
|||
|
||||
<div class="code"><pre>%module swigexample
|
||||
%inline {
|
||||
template<class __scalar>
|
||||
__scalar mul(__scalar a,__scalar b) {
|
||||
return a*b;
|
||||
}
|
||||
template<class __scalar>
|
||||
__scalar mul(__scalar a, __scalar b) {
|
||||
return a*b;
|
||||
}
|
||||
}
|
||||
%include <std_complex.i>
|
||||
%template(mul) mul<std::complex<double> >
|
||||
|
|
@ -677,11 +684,11 @@ and then used from Octave
|
|||
</p>
|
||||
|
||||
<div class="targetlang"><pre>
|
||||
octave:1> mul(4,3)
|
||||
octave:1> mul(4, 3)
|
||||
ans = 12
|
||||
octave:2> mul(4.2,3.6)
|
||||
octave:2> mul(4.2, 3.6)
|
||||
ans = 15.120
|
||||
octave:3> mul(3+4i,10+2i)
|
||||
octave:3> mul(3+4i, 10+2i)
|
||||
ans = 22 + 46i
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -722,11 +729,11 @@ octave:2> a=sum_complex(2+3i);
|
|||
octave:3> a.add(2)
|
||||
ans =
|
||||
|
||||
(4,3)
|
||||
(4, 3)
|
||||
octave:4> a.add(3+i)
|
||||
ans =
|
||||
|
||||
(7,4)
|
||||
(7, 4)
|
||||
</pre></div>
|
||||
|
||||
|
||||
|
|
@ -766,7 +773,7 @@ For example,
|
|||
<div class="targetlang"><pre>
|
||||
octave:1> a=subclass();
|
||||
octave:2> a.my_var = 4;
|
||||
octave:3> a.my_method = @(self) printf("my_var = ",self.my_var);
|
||||
octave:3> a.my_method = @(self) printf("my_var = ", self.my_var);
|
||||
octave:4> a.my_method();
|
||||
my_var = 4
|
||||
</pre></div>
|
||||
|
|
@ -790,7 +797,7 @@ void call_your_method(A& a) {
|
|||
Then from Octave you can say:
|
||||
</p>
|
||||
<div class="targetlang"><pre>
|
||||
octave:1> B=@() subclass(A(),@my_method);
|
||||
octave:1> B=@() subclass(A(), @my_method);
|
||||
octave:2> function my_method(self)
|
||||
octave:3> printf("octave-side routine called\n");
|
||||
octave:4> end
|
||||
|
|
@ -801,7 +808,7 @@ octave-side routine called
|
|||
or more concisely,
|
||||
</p>
|
||||
<div class="targetlang"><pre>
|
||||
octave:1> B=@() subclass(A(),'my_method',@(self) printf("octave-side routine called\n"));
|
||||
octave:1> B=@() subclass(A(), 'my_method', @(self) printf("octave-side routine called\n"));
|
||||
octave:2> call_your_method(B());
|
||||
octave-side routine called
|
||||
</pre></div>
|
||||
|
|
@ -809,10 +816,10 @@ octave-side routine called
|
|||
Note that you have to enable directors via the %feature directive (see other modules for this).
|
||||
</p>
|
||||
<p>
|
||||
<tt>subclass()</tt> will accept any number of C++ bases or other <tt>subclass()</tt>'ed objects, <tt>(string,octave_value)</tt> pairs, and <tt>function_handles</tt>. In the first case, these are taken as base classes; in the second case, as named members (either variables or functions, depending on whether the given value is a function handle); in the third case, as member functions whose name is taken from the given function handle. E.g.,
|
||||
<tt>subclass()</tt> will accept any number of C++ bases or other <tt>subclass()</tt>'ed objects, <tt>(string, octave_value)</tt> pairs, and <tt>function_handles</tt>. In the first case, these are taken as base classes; in the second case, as named members (either variables or functions, depending on whether the given value is a function handle); in the third case, as member functions whose name is taken from the given function handle. E.g.,
|
||||
</p>
|
||||
<div class="targetlang"><pre>
|
||||
octave:1> B=@(some_var=2) subclass(A(),'some_var',some_var,@some_func,'another_func',
|
||||
octave:1> B=@(some_var=2) subclass(A(), 'some_var', some_var, @some_func, 'another_func',
|
||||
@(self) do_stuff())
|
||||
</pre></div>
|
||||
<p>
|
||||
|
|
@ -822,7 +829,7 @@ You can also assign non-C++ member variables and functions after construct time.
|
|||
There is limited support for explicitly referencing C++ bases. So, in the example above, we could have
|
||||
</p>
|
||||
<div class="targetlang"><pre>
|
||||
octave:1> B=@() subclass(A(),@my_method);
|
||||
octave:1> B=@() subclass(A(), @my_method);
|
||||
octave:2> function my_method(self)
|
||||
octave:3> self.A.my_method();
|
||||
octave:4> printf("octave-side routine called\n");
|
||||
|
|
@ -887,7 +894,7 @@ Various STL library files are provided for wrapping STL containers.
|
|||
Octave provides a rich set of classes for dealing with matrices. Currently there are no built-in typemaps to deal with those. However, these are relatively straight forward for users to add themselves (see the docs on typemaps). Without much work (a single typemap decl-- say, 5 lines of code in the interface file), it would be possible to have a function
|
||||
</p>
|
||||
<div class="code"><pre>
|
||||
double my_det(const double* mat,int m,int n);
|
||||
double my_det(const double* mat, int m, int n);
|
||||
</pre></div>
|
||||
<p>
|
||||
that is accessed from Octave as,
|
||||
|
|
|
|||
|
|
@ -197,7 +197,7 @@ SWIG tries to guess the right options when it is installed. Therefore,
|
|||
you may want to start with one of the examples in the <tt>SWIG/Examples/perl5</tt>
|
||||
directory. If that doesn't work, you will need to read the man-pages for
|
||||
your compiler and linker to get the right set of options. You might also
|
||||
check the <a href="http://www.dabeaz.com/cgi-bin/wiki.pl">SWIG Wiki</a> for
|
||||
check the <a href="https://github.com/swig/swig/wiki">SWIG Wiki</a> for
|
||||
additional information.
|
||||
</p>
|
||||
|
||||
|
|
@ -322,7 +322,7 @@ all goes well, you will be able to do this:
|
|||
<div class="targetlang"><pre>
|
||||
$ perl
|
||||
use example;
|
||||
print example::fact(4),"\n";
|
||||
print example::fact(4), "\n";
|
||||
24
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -770,7 +770,7 @@ is accessed as follows:</p>
|
|||
|
||||
<div class="targetlang"><pre>
|
||||
use example;
|
||||
print $example::Spam,"\n";
|
||||
print $example::Spam, "\n";
|
||||
$example::Spam = $example::Spam + 4
|
||||
# ... etc ...
|
||||
|
||||
|
|
@ -841,7 +841,7 @@ In Perl:
|
|||
<div class="targetlang">
|
||||
<pre>
|
||||
use example;
|
||||
print $example::FOO,"\n"; # OK
|
||||
print $example::FOO, "\n"; # OK
|
||||
$example::FOO = 2; # Error
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -855,7 +855,7 @@ usually gives a more natural Perl interface, for example:
|
|||
<div class="targetlang">
|
||||
<pre>
|
||||
use example;
|
||||
print example::FOO,"\n";
|
||||
print example::FOO, "\n";
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -940,12 +940,12 @@ example:
|
|||
%inline %{
|
||||
/* C-style cast */
|
||||
Bar *FooToBar(Foo *f) {
|
||||
return (Bar *) f;
|
||||
return (Bar *) f;
|
||||
}
|
||||
|
||||
/* C++-style cast */
|
||||
Foo *BarToFoo(Bar *b) {
|
||||
return dynamic_cast<Foo*>(b);
|
||||
return dynamic_cast<Foo*>(b);
|
||||
}
|
||||
|
||||
Foo *IncrFoo(Foo *f, int i) {
|
||||
|
|
@ -978,7 +978,7 @@ accessor functions as described in the "SWIG Basics" chapter. For example,
|
|||
|
||||
<div class="code"><pre>
|
||||
struct Vector {
|
||||
double x,y,z;
|
||||
double x, y, z;
|
||||
};
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -1004,8 +1004,8 @@ These functions are then used to access structure data from Perl as follows:
|
|||
|
||||
<div class="targetlang"><pre>
|
||||
$v = example::new_Vector();
|
||||
print example::Vector_x_get($v),"\n"; # Get x component
|
||||
example::Vector_x_set($v,7.8); # Change x component
|
||||
print example::Vector_x_get($v), "\n"; # Get x component
|
||||
example::Vector_x_set($v, 7.8); # Change x component
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
|
|
@ -1020,12 +1020,12 @@ can also be forced to be read-only using the <tt>%immutable</tt> directive. For
|
|||
<div class="code">
|
||||
<pre>
|
||||
struct Foo {
|
||||
...
|
||||
%immutable;
|
||||
int x; /* Read-only members */
|
||||
char *name;
|
||||
%mutable;
|
||||
...
|
||||
...
|
||||
%immutable;
|
||||
int x; /* Read-only members */
|
||||
char *name;
|
||||
%mutable;
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1045,7 +1045,7 @@ Array members are normally wrapped as read-only. For example,
|
|||
<div class="code">
|
||||
<pre>
|
||||
struct Foo {
|
||||
int x[50];
|
||||
int x[50];
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1076,11 +1076,11 @@ When structure members are wrapped, they are handled as pointers. For example,
|
|||
<div class="code">
|
||||
<pre>
|
||||
struct Foo {
|
||||
...
|
||||
...
|
||||
};
|
||||
|
||||
struct Bar {
|
||||
Foo f;
|
||||
Foo f;
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1148,14 +1148,14 @@ In Perl, these functions are used in a straightforward manner:
|
|||
<div class="targetlang"><pre>
|
||||
use example;
|
||||
$l = example::new_List();
|
||||
example::List_insert($l,"Ale");
|
||||
example::List_insert($l,"Stout");
|
||||
example::List_insert($l,"Lager")
|
||||
example::List_insert($l, "Ale");
|
||||
example::List_insert($l, "Stout");
|
||||
example::List_insert($l, "Lager")
|
||||
example::List_print($l)
|
||||
Lager
|
||||
Stout
|
||||
Ale
|
||||
print example::List_length_get($l),"\n";
|
||||
print example::List_length_get($l), "\n";
|
||||
3
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -1222,9 +1222,9 @@ void foo(char *c); // Stays 'foo' (not renamed)
|
|||
|
||||
class Spam {
|
||||
public:
|
||||
void foo(int); // Becomes 'foo_i'
|
||||
void foo(double); // Becomes 'foo_d'
|
||||
...
|
||||
void foo(int); // Becomes 'foo_i'
|
||||
void foo(double); // Becomes 'foo_d'
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1238,8 +1238,8 @@ Now, in Perl, the methods are accessed as follows:
|
|||
use example;
|
||||
example::foo_i(3);
|
||||
$s = example::new_Spam();
|
||||
example::Spam_foo_i($s,3);
|
||||
example::Spam_foo_d($s,3.14);
|
||||
example::Spam_foo_i($s, 3);
|
||||
example::Spam_foo_d($s, 3.14);
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -1286,7 +1286,7 @@ a single Perl module. The name of the module is determined by the
|
|||
<div class="targetlang"><pre>
|
||||
$ perl5
|
||||
use example; # load the example module
|
||||
print example::fact(4),"\n" # Call a function in it
|
||||
print example::fact(4), "\n" # Call a function in it
|
||||
24
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -1365,7 +1365,7 @@ all of the functions in that module will be installed into the package
|
|||
|
||||
<div class="targetlang"><pre>
|
||||
use example; # Load the module like before
|
||||
print Foo::fact(4),"\n"; # Call a function in package FooBar
|
||||
print Foo::fact(4), "\n"; # Call a function in package FooBar
|
||||
</pre></div>
|
||||
-->
|
||||
|
||||
|
|
@ -1380,7 +1380,7 @@ example:
|
|||
<div class="code">
|
||||
<pre>
|
||||
void add(int x, int y, int *result) {
|
||||
*result = x + y;
|
||||
*result = x + y;
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1392,7 +1392,7 @@ or perhaps
|
|||
<div class="code">
|
||||
<pre>
|
||||
int sub(int *x, int *y) {
|
||||
return *x+*y;
|
||||
return *x+*y;
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1417,10 +1417,10 @@ In Perl, this allows you to pass simple values. For example:
|
|||
|
||||
<div class="targetlang">
|
||||
<pre>
|
||||
$a = example::add(3,4);
|
||||
$a = example::add(3, 4);
|
||||
print "$a\n";
|
||||
7
|
||||
$b = example::sub(7,4);
|
||||
$b = example::sub(7, 4);
|
||||
print "$b\n";
|
||||
3
|
||||
</pre>
|
||||
|
|
@ -1456,7 +1456,7 @@ If a function mutates one of its parameters like this,
|
|||
<div class="code">
|
||||
<pre>
|
||||
void negate(int *x) {
|
||||
*x = -(*x);
|
||||
*x = -(*x);
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1552,7 +1552,7 @@ Now, in Perl:
|
|||
|
||||
<div class="targetlang">
|
||||
<pre>
|
||||
($r,$c) = example::get_dimensions($m);
|
||||
($r, $c) = example::get_dimensions($m);
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -1578,7 +1578,7 @@ In Perl:
|
|||
<pre>
|
||||
use example;
|
||||
$c = 0.0;
|
||||
example::add(3,4,\$c);
|
||||
example::add(3, 4, \$c);
|
||||
print "$c\n";
|
||||
7
|
||||
</pre>
|
||||
|
|
@ -1614,7 +1614,7 @@ class DoubleArray {
|
|||
}
|
||||
// Destroy an array
|
||||
~DoubleArray() {
|
||||
delete ptr;
|
||||
delete ptr;
|
||||
}
|
||||
// Return the length of the array
|
||||
int length() {
|
||||
|
|
@ -1830,7 +1830,7 @@ the typemap system follows <tt>typedef</tt> declarations. For example:
|
|||
<pre>
|
||||
%typemap(in) int n {
|
||||
$1 = (int) SvIV($input);
|
||||
printf("n = %d\n",$1);
|
||||
printf("n = %d\n", $1);
|
||||
}
|
||||
%inline %{
|
||||
typedef int Integer;
|
||||
|
|
@ -1852,7 +1852,7 @@ Typemaps can also be defined for groups of consecutive arguments. For example:
|
|||
<div class="targetlang">
|
||||
<pre>
|
||||
%typemap(in) (char *str, unsigned len) {
|
||||
$1 = SvPV($input,$2);
|
||||
$1 = SvPV($input, $2);
|
||||
};
|
||||
|
||||
int count(char c, char *str, unsigned len);
|
||||
|
|
@ -1867,7 +1867,7 @@ parameter is omitted):
|
|||
|
||||
<div class="targetlang">
|
||||
<pre>
|
||||
example::count("e","Hello World");
|
||||
example::count("e", "Hello World");
|
||||
1
|
||||
>>>
|
||||
</pre>
|
||||
|
|
@ -2156,7 +2156,7 @@ reference to be used as a char ** datatype.
|
|||
$1 = (char **) malloc((len+2)*sizeof(char *));
|
||||
for (i = 0; i <= len; i++) {
|
||||
tv = av_fetch(tempav, i, 0);
|
||||
$1[i] = (char *) SvPV(*tv,PL_na);
|
||||
$1[i] = (char *) SvPV(*tv, PL_na);
|
||||
}
|
||||
$1[i] = NULL;
|
||||
};
|
||||
|
|
@ -2170,16 +2170,16 @@ reference to be used as a char ** datatype.
|
|||
%typemap(out) char ** {
|
||||
AV *myav;
|
||||
SV **svs;
|
||||
int i = 0,len = 0;
|
||||
int i = 0, len = 0;
|
||||
/* Figure out how many elements we have */
|
||||
while ($1[len])
|
||||
len++;
|
||||
len++;
|
||||
svs = (SV **) malloc(len*sizeof(SV *));
|
||||
for (i = 0; i < len ; i++) {
|
||||
svs[i] = sv_newmortal();
|
||||
sv_setpv((SV*)svs[i],$1[i]);
|
||||
svs[i] = sv_newmortal();
|
||||
sv_setpv((SV*)svs[i], $1[i]);
|
||||
};
|
||||
myav = av_make(len,svs);
|
||||
myav = av_make(len, svs);
|
||||
free(svs);
|
||||
$result = newRV_noinc((SV*)myav);
|
||||
sv_2mortal($result);
|
||||
|
|
@ -2188,20 +2188,20 @@ reference to be used as a char ** datatype.
|
|||
|
||||
// Now a few test functions
|
||||
%inline %{
|
||||
int print_args(char **argv) {
|
||||
int print_args(char **argv) {
|
||||
int i = 0;
|
||||
while (argv[i]) {
|
||||
printf("argv[%d] = %s\n", i,argv[i]);
|
||||
i++;
|
||||
printf("argv[%d] = %s\n", i, argv[i]);
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
// Returns a char ** list
|
||||
char **get_args() {
|
||||
// Returns a char ** list
|
||||
char **get_args() {
|
||||
static char *values[] = { "Dave", "Mike", "Susan", "John", "Michelle", 0};
|
||||
return &values[0];
|
||||
}
|
||||
}
|
||||
%}
|
||||
|
||||
</pre></div>
|
||||
|
|
@ -2216,7 +2216,7 @@ use argv;
|
|||
@a = ("Dave", "Mike", "John", "Mary"); # Create an array of strings
|
||||
argv::print_args(\@a); # Pass it to our C function
|
||||
$b = argv::get_args(); # Get array of strings from C
|
||||
print @$b,"\n"; # Print it out
|
||||
print @$b, "\n"; # Print it out
|
||||
</pre></div>
|
||||
|
||||
|
||||
|
|
@ -2241,10 +2241,10 @@ can be done using the <tt>EXTEND()</tt> macro as in:
|
|||
<div class="code"><pre>
|
||||
%typemap(argout) int *OUTPUT {
|
||||
if (argvi >= items) {
|
||||
EXTEND(sp,1); /* Extend the stack by 1 object */
|
||||
EXTEND(sp, 1); /* Extend the stack by 1 object */
|
||||
}
|
||||
$result = sv_newmortal();
|
||||
sv_setiv($target,(IV) *($1));
|
||||
sv_setiv($target, (IV) *($1));
|
||||
argvi++;
|
||||
}
|
||||
</pre></div>
|
||||
|
|
@ -2271,7 +2271,7 @@ its arguments. This example describes the implementation of the <tt>OUTPUT</tt>
|
|||
|
||||
// We don't care what the input value is. Ignore, but set to a temporary variable
|
||||
|
||||
%typemap(in,numinputs=0) double *OUTPUT(double junk) {
|
||||
%typemap(in, numinputs=0) double *OUTPUT(double junk) {
|
||||
$1 = &junk;
|
||||
}
|
||||
|
||||
|
|
@ -2298,9 +2298,9 @@ For example:
|
|||
</p>
|
||||
|
||||
<div class="targetlang"><pre>
|
||||
@r = multout(7,13);
|
||||
print "multout(7,13) = @r\n";
|
||||
($x,$y) = multout(7,13);
|
||||
@r = multout(7, 13);
|
||||
print "multout(7, 13) = @r\n";
|
||||
($x, $y) = multout(7, 13);
|
||||
</pre></div>
|
||||
|
||||
<H3><a name="Perl5_nn36">33.8.4 Accessing array structure members</a></H3>
|
||||
|
|
@ -2349,10 +2349,10 @@ For example:
|
|||
|
||||
<div class="code"><pre>
|
||||
%typemap(memberin) int [ANY] {
|
||||
int i;
|
||||
for (i = 0; i < $1_dim0; i++) {
|
||||
$1[i] = $input[i];
|
||||
}
|
||||
int i;
|
||||
for (i = 0; i < $1_dim0; i++) {
|
||||
$1[i] = $input[i];
|
||||
}
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -2390,7 +2390,7 @@ A common misinterpretation of this function is the following Perl script:
|
|||
$a = 3.5;
|
||||
$b = 7.5;
|
||||
$c = 0.0; # Output value
|
||||
add($a,$b,\$c); # Place result in c (Except that it doesn't work)
|
||||
add($a, $b, \$c); # Place result in c (Except that it doesn't work)
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
|
|
@ -2426,7 +2426,7 @@ Now, if you place this before the add function, you can do this:
|
|||
$a = 3.5;
|
||||
$b = 7.5;
|
||||
$c = 0.0;
|
||||
add($a,$b,\$c); # Now it works!
|
||||
add($a, $b, \$c); # Now it works!
|
||||
print "$c\n";
|
||||
|
||||
</pre></div>
|
||||
|
|
@ -2477,7 +2477,9 @@ is usually accessed as follows:
|
|||
<div class="code">
|
||||
<pre>
|
||||
Foo *f;
|
||||
if (SWIG_ConvertPtr($input, (void **) &f, SWIGTYPE_p_Foo, 0) == -1) return NULL;
|
||||
if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &f, SWIGTYPE_p_Foo, 0))) {
|
||||
SWIG_exception_fail(SWIG_TypeError, "in method '$symname', expecting type Foo");
|
||||
}
|
||||
|
||||
SV *sv = sv_newmortal();
|
||||
SWIG_MakePtr(sv, f, SWIGTYPE_p_Foo, 0);
|
||||
|
|
@ -2492,7 +2494,9 @@ variable <tt>$1_descriptor</tt>. For example:
|
|||
<div class="code">
|
||||
<pre>
|
||||
%typemap(in) Foo * {
|
||||
if ((SWIG_ConvertPtr($input,(void **) &$1, $1_descriptor,0)) == -1) return NULL;
|
||||
if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor, 0))) {
|
||||
SWIG_exception_fail(SWIG_TypeError, "in method '$symname', expecting type Foo");
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2505,7 +2509,9 @@ For example:
|
|||
<div class="code">
|
||||
<pre>
|
||||
%typemap(in) Foo * {
|
||||
if ((SWIG_ConvertPtr($input,(void **) &$1, $descriptor(Foo *), 0)) == -1) return NULL;
|
||||
if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &$1, $descriptor(Foo *), 0))) {
|
||||
SWIG_exception_fail(SWIG_TypeError, "in method '$symname', expecting type Foo");
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2560,7 +2566,7 @@ Suppose you have the following SWIG interface file:
|
|||
struct Vector {
|
||||
Vector(double x, double y, double z);
|
||||
~Vector();
|
||||
double x,y,z;
|
||||
double x, y, z;
|
||||
};
|
||||
|
||||
</pre></div>
|
||||
|
|
@ -2602,7 +2608,7 @@ sub new () {
|
|||
$OWNER{$self} = 1;
|
||||
my %retval;
|
||||
tie %retval, "example::Vector", $self;
|
||||
return bless \%retval,"Vector";
|
||||
return bless \%retval, "Vector";
|
||||
}
|
||||
|
||||
sub DESTROY {
|
||||
|
|
@ -2616,25 +2622,25 @@ sub DESTROY {
|
|||
}
|
||||
|
||||
sub FETCH {
|
||||
my ($self,$field) = @_;
|
||||
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;
|
||||
tie %retval, $BLESSEDMEMBERS{$field}, $val;
|
||||
return bless \%retval, $BLESSEDMEMBERS{$field};
|
||||
}
|
||||
return $val;
|
||||
}
|
||||
|
||||
sub STORE {
|
||||
my ($self,$field,$newval) = @_;
|
||||
my ($self, $field, $newval) = @_;
|
||||
my $member_func = "vectorc::Vector_${field}_set";
|
||||
if (exists $BLESSEDMEMBERS{$field}) {
|
||||
&$member_func($self,tied(%{$newval}));
|
||||
&$member_func($self, tied(%{$newval}));
|
||||
} else {
|
||||
&$member_func($self,$newval);
|
||||
&$member_func($self, $newval);
|
||||
}
|
||||
}
|
||||
</pre></div>
|
||||
|
|
@ -2656,8 +2662,8 @@ To use our new proxy class we can simply do the following:
|
|||
|
||||
<div class="targetlang"><pre>
|
||||
# Perl code using Vector class
|
||||
$v = new Vector(2,3,4);
|
||||
$w = Vector->new(-1,-2,-3);
|
||||
$v = new Vector(2, 3, 4);
|
||||
$w = Vector->new(-1, -2, -3);
|
||||
|
||||
# Assignment of a single member
|
||||
$v->{x} = 7.5;
|
||||
|
|
@ -2700,7 +2706,7 @@ Vector object:
|
|||
<div class="code"><pre>
|
||||
Vector *new_Vector(double x, double y, double z) {
|
||||
Vector *v;
|
||||
v = new Vector(x,y,z); // Call C++ constructor
|
||||
v = new Vector(x, y, z); // Call C++ constructor
|
||||
return v;
|
||||
}
|
||||
</pre></div>
|
||||
|
|
@ -2741,7 +2747,7 @@ done using the <tt>DISOWN</tt> method.
|
|||
|
||||
<div class="targetlang"><pre>
|
||||
# Perl code to change ownership of an object
|
||||
$v = new Vector(x,y,z);
|
||||
$v = new Vector(x, y, z);
|
||||
$v->DISOWN();
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -2996,10 +3002,10 @@ low-level helper functions. For example, this code now seems to work:
|
|||
<div class="targetlang">
|
||||
<pre>
|
||||
my $a =
|
||||
[[1,0,0,0],
|
||||
[0,1,0,0],
|
||||
[0,0,1,0],
|
||||
[0,0,0,1]];
|
||||
[[1, 0, 0, 0],
|
||||
[0, 1, 0, 0],
|
||||
[0, 0, 1, 0],
|
||||
[0, 0, 0, 1]];
|
||||
set_transform($im, $a);
|
||||
</pre>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -49,19 +49,6 @@
|
|||
|
||||
|
||||
|
||||
<p>
|
||||
SWIG supports generating wrappers for PHP5. Support for PHP4 was removed
|
||||
in SWIG 1.3.37. The PHP developers are no longer making new PHP4 releases,
|
||||
and won't even be patching critical security issues after 2008-08-08, so it
|
||||
doesn't make much sense for SWIG to continue to support PHP4 now. If you
|
||||
really need to continue to use PHP4, just stick with SWIG 1.3.36.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Currently any PHP5 release should work, but we don't regularly test with
|
||||
PHP < 5.3.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In this chapter, we discuss SWIG's support of PHP. The PHP module
|
||||
was extensively rewritten in release 1.3.26, and support for generating
|
||||
|
|
@ -70,7 +57,17 @@ of the features available in some of the other languages.
|
|||
</p>
|
||||
|
||||
<p>
|
||||
In order to use this module, you will need to have a copy of the PHP5
|
||||
SWIG supports generating wrappers for PHP5 and PHP7. Support for PHP4 was removed
|
||||
in SWIG 1.3.37.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Currently any PHP5 or PHP7 release should work, but we don't regularly test with
|
||||
PHP < 5.3.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In order to use this module, you will need to have a copy of the PHP
|
||||
include files to compile the SWIG generated files. If you installed
|
||||
PHP from a binary package, you may need to install a "php-dev" or "php-devel"
|
||||
package for these to be installed. You can find out where these files are
|
||||
|
|
@ -84,12 +81,13 @@ available.
|
|||
|
||||
|
||||
<p>
|
||||
To build a PHP extension, run swig using the <tt>-php</tt> option as
|
||||
follows:
|
||||
To build a PHP extension, run swig using the <tt>-php5</tt> or
|
||||
<tt>-php7</tt> option as follows (<tt>-php</tt> is also supported
|
||||
and currently is an alias for <tt>-php5</tt>):
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
swig -php example.i
|
||||
swig -php7 example.i
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
|
|
@ -102,13 +100,18 @@ The third file,
|
|||
<tt>example.php</tt> can be included by PHP scripts. It attempts to
|
||||
dynamically load the extension and contains extra php code specified
|
||||
in the interface file. If wrapping C++ code with PHP classes, it will
|
||||
also contain PHP5 class wrappers.
|
||||
also contain PHP class wrappers.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
SWIG can generate PHP extensions from C++ libraries as well when
|
||||
given the <tt>-c++</tt> option. The support for C++ is discussed in
|
||||
more detail in <a href="#Php_nn2_6">section 27.2.6</a>.
|
||||
more detail in <a href="#Php_nn2_6">section 27.2.6</a>. The generated
|
||||
C++ wrapper will be called example_wrap.cpp (for PHP5) or
|
||||
example_wrap.cxx (for PHP7 where the default has been changed to align
|
||||
with SWIG's default for every other language). You can specify a
|
||||
different extension for the C++ wrapper using <tt>-cppext</tt> -
|
||||
e.g. if you want example_wrap.cc use <tt>-cppext cc</tt>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
|
@ -273,7 +276,8 @@ if(EASY_TO_MISPEL) {
|
|||
<p>
|
||||
The mis-spelled constant will become the string 'EASY_TO_MISPEL', which
|
||||
is treated as true by the if test, when the value of the intended constant
|
||||
would be treated as false!
|
||||
would be treated as false! Modern versions of PHP will at least issue
|
||||
a PHP notice by default when this happens.
|
||||
</p>
|
||||
|
||||
<H3><a name="Php_nn2_2">34.2.2 Global Variables</a></H3>
|
||||
|
|
@ -291,7 +295,7 @@ the use of automatically generated accessor functions.
|
|||
%inline %{
|
||||
double seki = 2;
|
||||
void print_seki() {
|
||||
zend_printf("seki is now %f\n",seki);
|
||||
zend_printf("seki is now %f\n", seki);
|
||||
}
|
||||
%}
|
||||
</pre></div>
|
||||
|
|
@ -459,7 +463,7 @@ One can include <b>cpointer.i</b> to generate PHP wrappers to <tt>int
|
|||
<div class="code"><pre>
|
||||
%module example
|
||||
%include "cpointer.i"
|
||||
%pointer_functions(int,intp)
|
||||
%pointer_functions(int, intp)
|
||||
|
||||
void add( int *in1, int *in2, int *result);
|
||||
</pre></div>
|
||||
|
|
@ -509,7 +513,7 @@ include("example.php");
|
|||
|
||||
$in1 = 3;
|
||||
$in2 = 5;
|
||||
$result= add($in1,$in2); # Note using variables for the input is unnecessary.
|
||||
$result= add($in1, $in2); # Note using variables for the input is unnecessary.
|
||||
|
||||
echo "The sum $in1 + $in2 = $result\n";
|
||||
?>
|
||||
|
|
@ -555,7 +559,7 @@ include("example.php");
|
|||
$in1 = 3;
|
||||
$in2 = 5;
|
||||
$result = 0;
|
||||
add($in1,$in2,$result);
|
||||
add($in1, $in2, $result);
|
||||
|
||||
echo "The sum $in1 + $in2 = $result\n";
|
||||
?>
|
||||
|
|
@ -599,7 +603,7 @@ This interface file
|
|||
|
||||
class Vector {
|
||||
public:
|
||||
double x,y,z;
|
||||
double x, y, z;
|
||||
Vector();
|
||||
~Vector();
|
||||
double magnitude();
|
||||
|
|
@ -611,7 +615,7 @@ struct Complex {
|
|||
</pre></div>
|
||||
|
||||
<p>
|
||||
Would be used in the following way from PHP5:
|
||||
Would be used in the following way from PHP:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
|
|
@ -623,7 +627,7 @@ Would be used in the following way from PHP5:
|
|||
$v->y = 4;
|
||||
$v->z = 5;
|
||||
|
||||
echo "Magnitude of ($v->x,$v->y,$v->z) = " . $v->magnitude() . "\n";
|
||||
echo "Magnitude of ($v->x, $v->y, $v->z) = " . $v->magnitude() . "\n";
|
||||
|
||||
$v = NULL; # destructor called.
|
||||
|
||||
|
|
@ -646,23 +650,23 @@ Member variables and methods are accessed using the <tt>-></tt> operator.
|
|||
<p>
|
||||
The <tt>-noproxy</tt> option flattens the object structure and
|
||||
generates collections of named functions (these are the functions
|
||||
which the PHP5 class wrappers call). The above example results
|
||||
which the PHP class wrappers call). The above example results
|
||||
in the following PHP functions:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
new_Vector();
|
||||
Vector_x_set($obj,$d);
|
||||
Vector_x_set($obj, $d);
|
||||
Vector_x_get($obj);
|
||||
Vector_y_set($obj,$d);
|
||||
Vector_y_set($obj, $d);
|
||||
Vector_y_get($obj);
|
||||
Vector_z_set($obj,$d);
|
||||
Vector_z_set($obj, $d);
|
||||
Vector_z_get($obj);
|
||||
Vector_magnitude($obj);
|
||||
new_Complex();
|
||||
Complex_re_set($obj,$d);
|
||||
Complex_re_set($obj, $d);
|
||||
Complex_re_get($obj);
|
||||
Complex_im_set($obj,$d);
|
||||
Complex_im_set($obj, $d);
|
||||
Complex_im_get($obj);
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -816,6 +820,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.
|
||||
|
|
@ -995,7 +1008,7 @@ require("mymodule.php");
|
|||
|
||||
class MyFoo extends Foo {
|
||||
function one() {
|
||||
print "one from php\n";
|
||||
print "one from php\n";
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
|
|
@ -1143,12 +1156,20 @@ deleting all the Foo pointers it contains at some point.
|
|||
|
||||
<p>
|
||||
With directors routing method calls to PHP, and proxies routing them
|
||||
to C++, the handling of exceptions is an important concern. By default, the
|
||||
directors ignore exceptions that occur during method calls that are
|
||||
resolved in PHP. To handle such exceptions correctly, it is necessary
|
||||
to temporarily translate them into C++ exceptions. This can be done with
|
||||
the %feature("director:except") directive. The following code should
|
||||
suffice in most cases:
|
||||
to C++, the handling of exceptions is an important concern. By default, an
|
||||
exception thrown in PHP code called from C++ causes the PHP interpreter
|
||||
to flag that an exception is thrown, then return passes to C++ as if
|
||||
the PHP function had returned <code>Null</code>. Assuming the directorout
|
||||
typemaps handle this (those SWIG defines by default should) then once
|
||||
control returns to PHP code again, the PHP exception will actually propagate.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Sometimes this control flow is problematic, and you want to skip any
|
||||
handling in the C++ code. To achieve this, it is necessary
|
||||
to temporarily translate the PHP exception into a C++ exception. This can be
|
||||
achieved using the %feature("director:except") directive. The following code
|
||||
should suffice in most cases:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
|
|
|
|||
|
|
@ -125,7 +125,9 @@ SWIGMZSCHEME Defined when using Mzscheme
|
|||
SWIGOCAML Defined when using Ocaml
|
||||
SWIGOCTAVE Defined when using Octave
|
||||
SWIGPERL Defined when using Perl
|
||||
SWIGPHP Defined when using PHP
|
||||
SWIGPHP Defined when using PHP5 or PHP7
|
||||
SWIGPHP5 Defined when using PHP5
|
||||
SWIGPHP7 Defined when using PHP7
|
||||
SWIGPIKE Defined when using Pike
|
||||
SWIGPYTHON Defined when using Python
|
||||
SWIGR Defined when using R
|
||||
|
|
@ -222,19 +224,19 @@ For example:
|
|||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%define ARRAYHELPER(type,name)
|
||||
%define ARRAYHELPER(type, name)
|
||||
%inline %{
|
||||
type *new_ ## name (int nitems) {
|
||||
return (type *) malloc(sizeof(type)*nitems);
|
||||
return (type *) malloc(sizeof(type)*nitems);
|
||||
}
|
||||
void delete_ ## name(type *t) {
|
||||
free(t);
|
||||
free(t);
|
||||
}
|
||||
type name ## _get(type *t, int index) {
|
||||
return t[index];
|
||||
return t[index];
|
||||
}
|
||||
void name ## _set(type *t, int index, type val) {
|
||||
t[index] = val;
|
||||
t[index] = val;
|
||||
}
|
||||
%}
|
||||
%enddef
|
||||
|
|
@ -267,7 +269,7 @@ SWIG-1.3.12 and newer releases support variadic preprocessor macros. For exampl
|
|||
|
||||
<div class="code">
|
||||
<pre>
|
||||
#define DEBUGF(fmt,...) fprintf(stderr,fmt,__VA_ARGS__)
|
||||
#define DEBUGF(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__)
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -279,12 +281,12 @@ macros defined using <tt>%define</tt>.
|
|||
|
||||
<p>
|
||||
SWIG allows a variable number of arguments to be empty. However, this often results
|
||||
in an extra comma (,) and syntax error in the resulting expansion. For example:
|
||||
in an extra comma (, ) and syntax error in the resulting expansion. For example:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
DEBUGF("hello"); --> fprintf(stderr,"hello",);
|
||||
DEBUGF("hello"); --> fprintf(stderr, "hello", );
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -294,7 +296,7 @@ To get rid of the extra comma, use <tt>##</tt> like this:
|
|||
|
||||
<div class="code">
|
||||
<pre>
|
||||
#define DEBUGF(fmt,...) fprintf(stderr,fmt, ##__VA_ARGS__)
|
||||
#define DEBUGF(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__)
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -304,7 +306,7 @@ SWIG also supports GNU-style variadic macros. For example:
|
|||
|
||||
<div class="code">
|
||||
<pre>
|
||||
#define DEBUGF(fmt, args...) fprintf(stdout,fmt,args)
|
||||
#define DEBUGF(fmt, args...) fprintf(stdout, fmt, args)
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -334,7 +336,7 @@ if you write code like this,
|
|||
%{
|
||||
#ifdef NEED_BLAH
|
||||
int blah() {
|
||||
...
|
||||
...
|
||||
}
|
||||
#endif
|
||||
%}
|
||||
|
|
@ -358,11 +360,11 @@ file. For example:
|
|||
<div class="code">
|
||||
<pre>
|
||||
%extend Foo {
|
||||
void bar() {
|
||||
#ifdef DEBUG
|
||||
printf("I'm in bar\n");
|
||||
#endif
|
||||
}
|
||||
void bar() {
|
||||
#ifdef DEBUG
|
||||
printf("I'm in bar\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -375,11 +377,11 @@ to actually go into the wrapper file, prefix the preprocessor directives with <t
|
|||
<div class="code">
|
||||
<pre>
|
||||
%extend Foo {
|
||||
void bar() {
|
||||
%#ifdef DEBUG
|
||||
printf("I'm in bar\n");
|
||||
%#endif
|
||||
}
|
||||
void bar() {
|
||||
%#ifdef DEBUG
|
||||
printf("I'm in bar\n");
|
||||
%#endif
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -423,7 +425,7 @@ whereas
|
|||
<div class="code">
|
||||
<pre>
|
||||
#define SWIG_macro(CAST) (CAST)$input
|
||||
%typemap(in,noblock=1) Int {$1= SWIG_macro(int);}
|
||||
%typemap(in, noblock=1) Int {$1= SWIG_macro(int);}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -129,7 +129,7 @@ These two files can be loaded in any order
|
|||
<li>If you do not set the output file name appropriately, you might see errors like
|
||||
<div class="shell">
|
||||
<pre>
|
||||
> fact(4)
|
||||
> fact(4)
|
||||
Error in .Call("R_swig_fact", s_arg1, as.logical(.copy), PACKAGE = "example") :
|
||||
"R_swig_fact" not available for .Call() for package "example"
|
||||
</pre>
|
||||
|
|
@ -146,7 +146,7 @@ file makeRData.R which contains the following
|
|||
|
||||
<pre>
|
||||
source('BigFile.R')
|
||||
save(list=ls(all=TRUE),file="BigFile.RData", compress=TRUE)
|
||||
save(list=ls(all=TRUE), file="BigFile.RData", compress=TRUE)
|
||||
q(save="no")
|
||||
</pre>
|
||||
|
||||
|
|
|
|||
|
|
@ -192,28 +192,13 @@ to compile this file and link it with the rest of your program. </p>
|
|||
|
||||
|
||||
<p> In order to compile the wrapper code, the compiler needs the <tt>ruby.h</tt>
|
||||
header file. This file is usually contained in a directory such as </p>
|
||||
|
||||
<div class="code shell diagram">
|
||||
<pre>/usr/lib/ruby/1.8/x86_64-linux-gnu/ruby.h
|
||||
/usr/include/ruby-2.1.0/ruby.h
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p> The exact location may vary on your machine, but the above
|
||||
location is typical. If you are not entirely sure where Ruby is
|
||||
installed, you can run Ruby to find out. For example: </p>
|
||||
header file and its dependencies, notably <tt>ruby/config.h</tt> which is
|
||||
found in a different, architecture-dependent, directory. The best way to find
|
||||
the compiler options needed to compile the code is to ask Ruby itself:</p>
|
||||
|
||||
<div class="code shell">
|
||||
<pre>$ ruby -e 'puts $:.join("\n")'
|
||||
/usr/local/lib/site_ruby/2.1.0
|
||||
/usr/local/lib/x86_64-linux-gnu/site_ruby
|
||||
/usr/local/lib/site_ruby
|
||||
/usr/lib/ruby/vendor_ruby/2.1.0
|
||||
/usr/lib/x86_64-linux-gnu/ruby/vendor_ruby/2.1.0
|
||||
/usr/lib/ruby/vendor_ruby
|
||||
/usr/lib/ruby/2.1.0
|
||||
/usr/lib/x86_64-linux-gnu/ruby/2.1.0
|
||||
<pre>$ ruby -rrbconfig -e 'puts "-I#{RbConfig::CONFIG[%q{rubyhdrdir}]} -I#{RbConfig::CONFIG[%q{rubyarchhdrdir}]}"'
|
||||
-I/usr/include/ruby-2.1.0 -I/usr/include/x86_64-linux-gnu/ruby-2.1.0
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -287,7 +272,7 @@ processes). Other compilers may need a different option specified instead of
|
|||
<p>
|
||||
If in doubt, consult the
|
||||
manual pages for your compiler and linker to determine the correct set
|
||||
of options. You might also check the <a href="http://www.dabeaz.com/cgi-bin/wiki.pl">SWIG Wiki</a>
|
||||
of options. You might also check the <a href="https://github.com/swig/swig/wiki">SWIG Wiki</a>
|
||||
for additional information. </p>
|
||||
|
||||
<H3><a name="Ruby_nn6">38.1.4 Using your module</a></H3>
|
||||
|
|
@ -1014,7 +999,7 @@ void foo(char *c);</pre>
|
|||
irb(main):002:0> <b>foo("Hello")</b> # foo(char *c)</pre>
|
||||
</div>
|
||||
|
||||
<p>Similarly, if you have a class like this,</p>
|
||||
<p>Similarly, if you have a class like this, </p>
|
||||
|
||||
<div class="code">
|
||||
<pre>class Foo {
|
||||
|
|
@ -1141,7 +1126,7 @@ like this, </p>
|
|||
namespace foo {
|
||||
int fact(int n);
|
||||
struct Vector {
|
||||
double x,y,z;
|
||||
double x, y, z;
|
||||
};
|
||||
};</pre>
|
||||
</div>
|
||||
|
|
@ -1210,7 +1195,7 @@ struct pair {
|
|||
~pair();
|
||||
};
|
||||
|
||||
%template(Pairii) pair<int,int>;</pre>
|
||||
%template(Pairii) pair<int, int>;</pre>
|
||||
</div>
|
||||
|
||||
<p>In Ruby:</p>
|
||||
|
|
@ -1273,7 +1258,7 @@ v.each { |x| puts x }
|
|||
3
|
||||
4
|
||||
v.delete_if { |x| x == 3 }
|
||||
=> [2,4]</pre>
|
||||
=> [2, 4]</pre>
|
||||
</div>
|
||||
|
||||
<p>The SWIG Ruby module provides also the ability for all the STL
|
||||
|
|
@ -1303,7 +1288,7 @@ include NativeVector
|
|||
|
||||
v = NativeVector.new
|
||||
v << 1
|
||||
v << [1,2]
|
||||
v << [1, 2]
|
||||
v << 'hello'
|
||||
|
||||
class A; end
|
||||
|
|
@ -1311,7 +1296,7 @@ class A; end
|
|||
v << A.new
|
||||
|
||||
puts v
|
||||
=> [1, [1,2], 'hello', #<A:0x245325>]
|
||||
=> [1, [1, 2], 'hello', #<A:0x245325>]
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -1368,15 +1353,15 @@ a << 1
|
|||
a << 2
|
||||
a << 3
|
||||
a
|
||||
<b>=> [1,2,3]</b>
|
||||
<b>=> [1, 2, 3]</b>
|
||||
|
||||
# Custom sorting behavior defined by a Ruby proc
|
||||
b = IntSet.new( proc { |a,b| a > b } )
|
||||
b = IntSet.new( proc { |a, b| a > b } )
|
||||
b << 1
|
||||
b << 2
|
||||
b << 3
|
||||
b
|
||||
<b>=> [3,2,1]</b>
|
||||
<b>=> [3, 2, 1]</b>
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -1493,7 +1478,7 @@ like this: </p>
|
|||
}</pre>
|
||||
</div>
|
||||
|
||||
<p>Then, if you have a class like this,</p>
|
||||
<p>Then, if you have a class like this, </p>
|
||||
|
||||
<div class="code">
|
||||
<pre>class Foo {
|
||||
|
|
@ -1665,7 +1650,7 @@ a comma-separated list of aliases to the <tt>%alias</tt>
|
|||
directive, e.g. </p>
|
||||
|
||||
<div class="code">
|
||||
<pre>%alias MyArray::length "amount,quantity,size";</pre>
|
||||
<pre>%alias MyArray::length "amount, quantity, size";</pre>
|
||||
</div>
|
||||
|
||||
<p> From an end-user's standpoint, there's no functional
|
||||
|
|
@ -1835,10 +1820,10 @@ int sub(int *INPUT, int *INPUT);</pre>
|
|||
<p>In Ruby, this allows you to pass simple values. For example:</p>
|
||||
|
||||
<div class="code targetlang">
|
||||
<pre>a = Example.add(3,4)
|
||||
<pre>a = Example.add(3, 4)
|
||||
puts a
|
||||
7
|
||||
b = Example.sub(7,4)
|
||||
b = Example.sub(7, 4)
|
||||
puts b
|
||||
3</pre>
|
||||
</div>
|
||||
|
|
@ -2086,7 +2071,7 @@ public:
|
|||
<p> Then, in ruby, it can be used like:</p>
|
||||
|
||||
<div class="targetlang"><pre>
|
||||
Window.new(0,0,360,480) { |w|
|
||||
Window.new(0, 0, 360, 480) { |w|
|
||||
w.color = Fltk::RED
|
||||
w.border = false
|
||||
}
|
||||
|
|
@ -2102,7 +2087,7 @@ a special in typemap, like:</p>
|
|||
//
|
||||
// void func(int x);
|
||||
|
||||
%typemap(in,numinputs=0) int RUBY_YIELD_SELF {
|
||||
%typemap(in, numinputs=0) int RUBY_YIELD_SELF {
|
||||
if ( !rb_block_given_p() )
|
||||
rb_raise("No block given");
|
||||
return rb_yield(self);
|
||||
|
|
@ -2384,7 +2369,7 @@ from Ruby to C, you might define a typemap like this: </p>
|
|||
|
||||
%typemap(in) int {
|
||||
$1 = (int) NUM2INT($input);
|
||||
printf("Received an integer : %d\n",$1);
|
||||
printf("Received an integer : %d\n", $1);
|
||||
}
|
||||
|
||||
%inline %{
|
||||
|
|
@ -2428,7 +2413,7 @@ supplying an optional parameter name. For example: </p>
|
|||
|
||||
%typemap(in) int n {
|
||||
$1 = (int) NUM2INT($input);
|
||||
printf("n = %d\n",$1);
|
||||
printf("n = %d\n", $1);
|
||||
}
|
||||
|
||||
%inline %{
|
||||
|
|
@ -2450,7 +2435,7 @@ declarations. For example: </p>
|
|||
<div class="code">
|
||||
<pre>%typemap(in) int n {
|
||||
$1 = (int) NUM2INT($input);
|
||||
printf("n = %d\n",$1);
|
||||
printf("n = %d\n", $1);
|
||||
}
|
||||
|
||||
typedef int Integer;
|
||||
|
|
@ -2478,7 +2463,7 @@ always handled as a single Ruby object. This allows the function <tt>count</tt>
|
|||
to be used as follows (notice how the length parameter is omitted): </p>
|
||||
|
||||
<div class="code targetlang">
|
||||
<pre>puts Example.count('o','Hello World')
|
||||
<pre>puts Example.count('o', 'Hello World')
|
||||
2</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -2747,7 +2732,7 @@ functions and methods. It merely checks an argument to see whether or
|
|||
not it matches a specific type. For example:</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>%typemap(typecheck,precedence=SWIG_TYPECHECK_INTEGER) int {
|
||||
<pre>%typemap(typecheck, precedence=SWIG_TYPECHECK_INTEGER) int {
|
||||
$1 = FIXNUM_P($input) ? 1 : 0;
|
||||
}</pre>
|
||||
</div>
|
||||
|
|
@ -2862,7 +2847,7 @@ arguments have been converted. For example:</p>
|
|||
<div class="code">
|
||||
<pre>%typemap(check) int positive {
|
||||
if ($1 <= 0) {
|
||||
SWIG_exception(SWIG_ValueError,"Expected positive value.");
|
||||
SWIG_exception(SWIG_ValueError, "Expected positive value.");
|
||||
}
|
||||
}</pre>
|
||||
</div>
|
||||
|
|
@ -3168,7 +3153,7 @@ directive. Thus, a function can be made to return "nothing"
|
|||
if you do:</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
%feature("numoutputs","0") MyClass::function;
|
||||
%feature("numoutputs", "0") MyClass::function;
|
||||
</pre></div>
|
||||
|
||||
<p>This feature can be useful if a function returns a status
|
||||
|
|
@ -3346,7 +3331,7 @@ across multiple languages.</p>
|
|||
</tr>
|
||||
<tr>
|
||||
<td>rb_float_new(double) </td>
|
||||
<td>SWIG_From_double(double),<br>
|
||||
<td>SWIG_From_double(double), <br>
|
||||
SWIG_From_float(float)</td>
|
||||
<td>float/double to Float</td>
|
||||
</tr>
|
||||
|
|
@ -3365,7 +3350,7 @@ versions do not, but return a status value to indicate success (<tt>SWIG_OK</tt>
|
|||
%typemap(in) size_t (int ok)
|
||||
ok = SWIG_AsVal_size_t($input, &$1);
|
||||
if (!SWIG_IsOK(ok)) {
|
||||
SWIG_exception_fail(SWIG_ArgError(ok), Ruby_Format_TypeError( "$1_name", "$1_type","$symname", $argnum, $input));
|
||||
SWIG_exception_fail(SWIG_ArgError(ok), Ruby_Format_TypeError( "$1_name", "$1_type", "$symname", $argnum, $input));
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
|
|
@ -3615,7 +3600,7 @@ Array instance to be used as a <tt>char **</tt> object. </p>
|
|||
int print_args(char **argv) {
|
||||
int i = 0;
|
||||
while (argv[i]) {
|
||||
printf("argv[%d] = %s\n", i,argv[i]);
|
||||
printf("argv[%d] = %s\n", i, argv[i]);
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
|
|
@ -3628,7 +3613,7 @@ operates as follows : </p>
|
|||
|
||||
<div class="code targetlang">
|
||||
<pre>require 'Argv'
|
||||
Argv.print_args(["Dave","Mike","Mary","Jane","John"])
|
||||
Argv.print_args(["Dave", "Mike", "Mary", "Jane", "John"])
|
||||
argv[0] = Dave
|
||||
argv[1] = Mike
|
||||
argv[2] = Mary
|
||||
|
|
@ -4591,7 +4576,7 @@ comma-separated list of module names to the <tt>%mixin</tt>
|
|||
directive, e.g. </p>
|
||||
|
||||
<div class="code">
|
||||
<pre>%mixin Set "Fee,Fi,Fo,Fum";</pre>
|
||||
<pre>%mixin Set "Fee, Fi, Fo, Fum";</pre>
|
||||
</div>
|
||||
|
||||
<p> Note that the <tt>%mixin</tt> directive is
|
||||
|
|
|
|||
|
|
@ -131,7 +131,8 @@ can be obtained by typing <tt>swig -help</tt> or <tt>swig
|
|||
-ocaml Generate Ocaml wrappers
|
||||
-octave Generate Octave wrappers
|
||||
-perl Generate Perl wrappers
|
||||
-php Generate PHP wrappers
|
||||
-php5 Generate PHP5 wrappers
|
||||
-php7 Generate PHP7 wrappers
|
||||
-pike Generate Pike wrappers
|
||||
-python Generate Python wrappers
|
||||
-r Generate R (aka GNU S) wrappers
|
||||
|
|
@ -142,23 +143,23 @@ can be obtained by typing <tt>swig -help</tt> or <tt>swig
|
|||
-uffi Generate Common Lisp / UFFI wrappers
|
||||
-xml Generate XML wrappers
|
||||
|
||||
-c++ Enable C++ parsing
|
||||
-c++ Enable C++ processing
|
||||
-cppext <em>ext</em> Change file extension of C++ generated files to <em>ext</em>
|
||||
(default is cxx, except for PHP which uses cpp)
|
||||
(default is cxx, except for PHP5 which uses cpp)
|
||||
-D<em>symbol</em> Define a preprocessor symbol
|
||||
-Fstandard Display error/warning messages in commonly used format
|
||||
-Fmicrosoft Display error/warning messages in Microsoft format
|
||||
-Fstandard Display error/warning messages in commonly used format
|
||||
-help Display all options
|
||||
-I<em>dir</em> Add a directory to the file include path
|
||||
-l<em>file</em> Include a SWIG library file.
|
||||
-l<em>ifile</em> Include SWIG library file <ifile>
|
||||
-module <em>name</em> Set the name of the SWIG module
|
||||
-o <em>outfile</em> Set name of C/C++ output file to <outfile>
|
||||
-oh <em>headfile</em> Set name of C++ output header file for directors to <headfile>
|
||||
-outcurrentdir Set default output dir to current dir instead of input file's path
|
||||
-outdir <em>dir</em> Set language specific files output directory
|
||||
-pcreversion Display PCRE version information
|
||||
-swiglib Show location of SWIG library
|
||||
-version Show SWIG version number
|
||||
-swiglib Report location of SWIG library and exit
|
||||
-version Display SWIG version number
|
||||
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -479,7 +480,7 @@ Or in Python:
|
|||
<div class="targetlang"><pre>
|
||||
>>> example.sin(3)
|
||||
5.2335956
|
||||
>>> example.strcmp('Dave','Mike')
|
||||
>>> example.strcmp('Dave', 'Mike')
|
||||
-1
|
||||
>>> print example.cvar.Foo
|
||||
42
|
||||
|
|
@ -648,7 +649,7 @@ print cvar.foo # Print value of foo
|
|||
|
||||
# Perl
|
||||
$foo = 3.5; # Set foo to 3.5
|
||||
print $foo,"\n"; # Print value of foo
|
||||
print $foo, "\n"; # Print value of foo
|
||||
|
||||
# Ruby
|
||||
Module.foo = 3.5 # Set foo to 3.5
|
||||
|
|
@ -749,7 +750,7 @@ form of type-checking however).</p>
|
|||
<p>
|
||||
For enumerations, it is critical that the original enum definition be
|
||||
included somewhere in the interface file (either in a header file or
|
||||
in the <tt>%{,%}</tt> block). SWIG only translates the enumeration
|
||||
in the <tt>%{ %}</tt> block). SWIG only translates the enumeration
|
||||
into code needed to add the constants to a scripting language. It
|
||||
needs the original enumeration declaration in order to get the correct
|
||||
enum values as assigned by the C compiler.
|
||||
|
|
@ -1041,14 +1042,14 @@ expect :</p>
|
|||
|
||||
<div class="targetlang"><pre>
|
||||
# Copy a file
|
||||
def filecopy(source,target):
|
||||
f1 = fopen(source,"r")
|
||||
f2 = fopen(target,"w")
|
||||
def filecopy(source, target):
|
||||
f1 = fopen(source, "r")
|
||||
f2 = fopen(target, "w")
|
||||
buffer = malloc(8192)
|
||||
nbytes = fread(buffer,8192,1,f1)
|
||||
nbytes = fread(buffer, 8192, 1, f1)
|
||||
while (nbytes > 0):
|
||||
fwrite(buffer,8192,1,f2)
|
||||
nbytes = fread(buffer,8192,1,f1)
|
||||
fwrite(buffer, 8192, 1, f2)
|
||||
nbytes = fread(buffer, 8192, 1, f1)
|
||||
free(buffer)
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -1237,7 +1238,7 @@ creating a wrapper equivalent to the following:
|
|||
double wrap_dot_product(Vector *a, Vector *b) {
|
||||
Vector x = *a;
|
||||
Vector y = *b;
|
||||
return dot_product(x,y);
|
||||
return dot_product(x, y);
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -1269,7 +1270,7 @@ Vector *wrap_cross_product(Vector *v1, Vector *v2) {
|
|||
Vector y = *v2;
|
||||
Vector *result;
|
||||
result = (Vector *) malloc(sizeof(Vector));
|
||||
*(result) = cross(x,y);
|
||||
*(result) = cross(x, y);
|
||||
return result;
|
||||
}
|
||||
</pre></div>
|
||||
|
|
@ -1281,7 +1282,7 @@ or if SWIG was run with the <tt>-c++</tt> option:</p>
|
|||
Vector *wrap_cross(Vector *v1, Vector *v2) {
|
||||
Vector x = *v1;
|
||||
Vector y = *v2;
|
||||
Vector *result = new Vector(cross(x,y)); // Uses default copy constructor
|
||||
Vector *result = new Vector(cross(x, y)); // Uses default copy constructor
|
||||
return result;
|
||||
}
|
||||
</pre></div>
|
||||
|
|
@ -1357,16 +1358,16 @@ SWIG generates the following code:
|
|||
<pre>
|
||||
/* C mode */
|
||||
void foo_set(char *value) {
|
||||
if (foo) free(foo);
|
||||
foo = (char *) malloc(strlen(value)+1);
|
||||
strcpy(foo,value);
|
||||
if (foo) free(foo);
|
||||
foo = (char *) malloc(strlen(value)+1);
|
||||
strcpy(foo, value);
|
||||
}
|
||||
|
||||
/* C++ mode. When -c++ option is used */
|
||||
void foo_set(char *value) {
|
||||
if (foo) delete [] foo;
|
||||
foo = new char[strlen(value)+1];
|
||||
strcpy(foo,value);
|
||||
if (foo) delete [] foo;
|
||||
foo = new char[strlen(value)+1];
|
||||
strcpy(foo, value);
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1381,8 +1382,8 @@ exactly like you want. For example:
|
|||
<pre>
|
||||
%inline %{
|
||||
void set_foo(char *value) {
|
||||
strncpy(foo,value, 50);
|
||||
}
|
||||
strncpy(foo, value, 50);
|
||||
}
|
||||
%}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1538,10 +1539,10 @@ a few simple assist functions like this:
|
|||
<pre>
|
||||
%inline %{
|
||||
void a_set(int i, int j, int val) {
|
||||
a[i][j] = val;
|
||||
a[i][j] = val;
|
||||
}
|
||||
int a_get(int i, int j) {
|
||||
return a[i][j];
|
||||
return a[i][j];
|
||||
}
|
||||
%}
|
||||
</pre>
|
||||
|
|
@ -1558,11 +1559,11 @@ some helper functions in your interface. For example:
|
|||
%inline %{
|
||||
/* Create any sort of [size] array */
|
||||
int *int_array(int size) {
|
||||
return (int *) malloc(size*sizeof(int));
|
||||
return (int *) malloc(size*sizeof(int));
|
||||
}
|
||||
/* Create a two-dimension array [size][10] */
|
||||
int (*int_array_10(int size))[10] {
|
||||
return (int (*)[10]) malloc(size*10*sizeof(int));
|
||||
return (int (*)[10]) malloc(size*10*sizeof(int));
|
||||
}
|
||||
%}
|
||||
</pre>
|
||||
|
|
@ -1587,10 +1588,10 @@ code:
|
|||
<div class="code">
|
||||
<pre>
|
||||
char *pathname_get() {
|
||||
return pathname;
|
||||
return pathname;
|
||||
}
|
||||
void pathname_set(char *value) {
|
||||
strncpy(pathname,value,256);
|
||||
strncpy(pathname, value, 256);
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1611,9 +1612,9 @@ directive as shown :</p>
|
|||
|
||||
int a; // Can read/write
|
||||
%immutable;
|
||||
int b,c,d; // Read only variables
|
||||
int b, c, d; // Read only variables
|
||||
%mutable;
|
||||
double x,y; // read/write
|
||||
double x, y; // read/write
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
|
|
@ -1638,7 +1639,7 @@ The <tt>%mutable</tt> and <tt>%immutable</tt> directives are actually
|
|||
|
||||
<div class="code"><pre>
|
||||
#define %immutable %feature("immutable")
|
||||
#define %mutable %feature("immutable","")
|
||||
#define %mutable %feature("immutable", "")
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
|
|
@ -1647,7 +1648,7 @@ If you wanted to make all wrapped variables read-only, barring one or two, it mi
|
|||
|
||||
<div class="code"><pre>
|
||||
%immutable; // Make all variables read-only
|
||||
%feature("immutable","0") x; // except, make x read/write
|
||||
%feature("immutable", "0") x; // except, make x read/write
|
||||
...
|
||||
double x;
|
||||
double y;
|
||||
|
|
@ -2172,7 +2173,7 @@ consider a function like this:
|
|||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
int binary_op(int a, int b, int (*op)(int,int));
|
||||
int binary_op(int a, int b, int (*op)(int, int));
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
|
|
@ -2181,10 +2182,10 @@ may find the function to be impossible to use. For instance, in Python:
|
|||
</p>
|
||||
|
||||
<div class="targetlang"><pre>
|
||||
>>> def add(x,y):
|
||||
>>> def add(x, y):
|
||||
... return x+y
|
||||
...
|
||||
>>> binary_op(3,4,add)
|
||||
>>> binary_op(3, 4, add)
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in ?
|
||||
TypeError: Type error. Expected _p_f_int_int__int
|
||||
|
|
@ -2201,12 +2202,12 @@ One way to do this is to use the <tt>%constant</tt> directive like this:
|
|||
|
||||
<div class="code"><pre>
|
||||
/* Function with a callback */
|
||||
int binary_op(int a, int b, int (*op)(int,int));
|
||||
int binary_op(int a, int b, int (*op)(int, int));
|
||||
|
||||
/* Some callback functions */
|
||||
%constant int add(int,int);
|
||||
%constant int sub(int,int);
|
||||
%constant int mul(int,int);
|
||||
%constant int add(int, int);
|
||||
%constant int sub(int, int);
|
||||
%constant int mul(int, int);
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
|
|
@ -2216,9 +2217,9 @@ constants in the target scripting language. This allows you to use them as foll
|
|||
|
||||
<div class="targetlang">
|
||||
<pre>
|
||||
>>> binary_op(3,4,add)
|
||||
>>> binary_op(3, 4, add)
|
||||
7
|
||||
>>> binary_op(3,4,mul)
|
||||
>>> binary_op(3, 4, mul)
|
||||
12
|
||||
>>>
|
||||
</pre>
|
||||
|
|
@ -2231,7 +2232,7 @@ as functions. For example:
|
|||
|
||||
<div class="targetlang">
|
||||
<pre>
|
||||
>>> add(3,4)
|
||||
>>> add(3, 4)
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in ?
|
||||
TypeError: object is not callable: '_ff020efc_p_f_int_int__int'
|
||||
|
|
@ -2247,13 +2248,13 @@ can use the <tt>%callback</tt> and <tt>%nocallback</tt> directives like this:
|
|||
<div class="code">
|
||||
<pre>
|
||||
/* Function with a callback */
|
||||
int binary_op(int a, int b, int (*op)(int,int));
|
||||
int binary_op(int a, int b, int (*op)(int, int));
|
||||
|
||||
/* Some callback functions */
|
||||
%callback("%s_cb");
|
||||
int add(int,int);
|
||||
int sub(int,int);
|
||||
int mul(int,int);
|
||||
int add(int, int);
|
||||
int sub(int, int);
|
||||
int mul(int, int);
|
||||
%nocallback;
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -2266,13 +2267,13 @@ disabled using <tt>%nocallback</tt>. When you do this, the interface now works
|
|||
|
||||
<div class="targetlang">
|
||||
<pre>
|
||||
>>> binary_op(3,4,add_cb)
|
||||
>>> binary_op(3, 4, add_cb)
|
||||
7
|
||||
>>> binary_op(3,4,mul_cb)
|
||||
>>> binary_op(3, 4, mul_cb)
|
||||
12
|
||||
>>> add(3,4)
|
||||
>>> add(3, 4)
|
||||
7
|
||||
>>> mul(3,4)
|
||||
>>> mul(3, 4)
|
||||
12
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2293,9 +2294,9 @@ variation installs the callbacks as all upper case constants such as
|
|||
<div class="code"><pre>
|
||||
/* Some callback functions */
|
||||
%callback("%(uppercase)s");
|
||||
int add(int,int);
|
||||
int sub(int,int);
|
||||
int mul(int,int);
|
||||
int add(int, int);
|
||||
int sub(int, int);
|
||||
int mul(int, int);
|
||||
%nocallback;
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -2331,7 +2332,7 @@ to an individual member. For example, the declaration :</p>
|
|||
|
||||
<div class="code"><pre>
|
||||
struct Vector {
|
||||
double x,y,z;
|
||||
double x, y, z;
|
||||
}
|
||||
|
||||
</pre></div>
|
||||
|
|
@ -2367,7 +2368,7 @@ 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);
|
||||
|
|
@ -2383,9 +2384,9 @@ language using code like this:
|
|||
<div class="code">
|
||||
<pre>
|
||||
v = new_Vector()
|
||||
Vector_x_set(v,2)
|
||||
Vector_y_set(v,10)
|
||||
Vector_z_set(v,-5)
|
||||
Vector_x_set(v, 2)
|
||||
Vector_y_set(v, 10)
|
||||
Vector_z_set(v, -5)
|
||||
...
|
||||
delete_Vector(v)
|
||||
</pre>
|
||||
|
|
@ -2404,7 +2405,7 @@ programs :</p>
|
|||
|
||||
<div class="code"><pre>
|
||||
typedef struct {
|
||||
double x,y,z;
|
||||
double x, y, z;
|
||||
} Vector;
|
||||
|
||||
</pre></div>
|
||||
|
|
@ -2429,7 +2430,7 @@ If two different names are used like this :</p>
|
|||
|
||||
<div class="code"><pre>
|
||||
typedef struct vector_struct {
|
||||
double x,y,z;
|
||||
double x, y, z;
|
||||
} Vector;
|
||||
|
||||
</pre></div>
|
||||
|
|
@ -2473,7 +2474,7 @@ char *Foo_name_set(Foo *obj, char *c) {
|
|||
if (obj->name)
|
||||
free(obj->name);
|
||||
obj->name = (char *) malloc(strlen(c)+1);
|
||||
strcpy(obj->name,c);
|
||||
strcpy(obj->name, c);
|
||||
return obj->name;
|
||||
}
|
||||
</pre></div>
|
||||
|
|
@ -2521,12 +2522,12 @@ Occasionally, a structure will contain data members that are themselves structur
|
|||
<div class="code">
|
||||
<pre>
|
||||
typedef struct Foo {
|
||||
int x;
|
||||
int x;
|
||||
} Foo;
|
||||
|
||||
typedef struct Bar {
|
||||
int y;
|
||||
Foo f; /* struct member */
|
||||
int y;
|
||||
Foo f; /* struct member */
|
||||
} Bar;
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2540,10 +2541,10 @@ The accessors to the member variable as a pointer are effectively wrapped as fol
|
|||
<div class="code">
|
||||
<pre>
|
||||
Foo *Bar_f_get(Bar *b) {
|
||||
return &b->f;
|
||||
return &b->f;
|
||||
}
|
||||
void Bar_f_set(Bar *b, Foo *value) {
|
||||
b->f = *value;
|
||||
b->f = *value;
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2570,7 +2571,7 @@ language interface) results in the following code:
|
|||
<div class="code">
|
||||
<pre>
|
||||
Bar *b;
|
||||
Foo_x_set(Bar_f_get(b),37);
|
||||
Foo_x_set(Bar_f_get(b), 37);
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -2588,7 +2589,7 @@ is a structure or class. For instance, if you had a structure like this,
|
|||
<div class="code">
|
||||
<pre>
|
||||
struct Foo {
|
||||
WORD w;
|
||||
WORD w;
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2726,7 +2727,7 @@ the following declaration :</p>
|
|||
/* file : vector.h */
|
||||
...
|
||||
typedef struct Vector {
|
||||
double x,y,z;
|
||||
double x, y, z;
|
||||
} Vector;
|
||||
|
||||
</pre></div>
|
||||
|
|
@ -2759,7 +2760,7 @@ You can make a <tt>Vector</tt> look a lot like a class by writing a SWIG interfa
|
|||
return sqrt($self->x*$self->x+$self->y*$self->y+$self->z*$self->z);
|
||||
}
|
||||
void print() {
|
||||
printf("Vector [%g, %g, %g]\n", $self->x,$self->y,$self->z);
|
||||
printf("Vector [%g, %g, %g]\n", $self->x, $self->y, $self->z);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -2779,7 +2780,7 @@ Now, when used with proxy classes in Python, you can do things like
|
|||
this :</p>
|
||||
|
||||
<div class="targetlang"><pre>
|
||||
>>> v = Vector(3,4,0) # Create a new vector
|
||||
>>> v = Vector(3, 4, 0) # Create a new vector
|
||||
>>> print v.magnitude() # Print magnitude
|
||||
5.0
|
||||
>>> v.print() # Print it out
|
||||
|
|
@ -2799,7 +2800,7 @@ of the Vector structure. For example:</p>
|
|||
%}
|
||||
|
||||
typedef struct Vector {
|
||||
double x,y,z;
|
||||
double x, y, z;
|
||||
%extend {
|
||||
Vector(double x, double y, double z) { ... }
|
||||
~Vector() { ... }
|
||||
|
|
@ -2841,12 +2842,12 @@ double Vector_magnitude(Vector *v) {
|
|||
%}
|
||||
|
||||
typedef struct Vector {
|
||||
double x,y,z;
|
||||
double x, y, z;
|
||||
%extend {
|
||||
Vector(int,int,int); // This calls new_Vector()
|
||||
~Vector(); // This calls delete_Vector()
|
||||
double magnitude(); // This will call Vector_magnitude()
|
||||
...
|
||||
Vector(int, int, int); // This calls new_Vector()
|
||||
~Vector(); // This calls delete_Vector()
|
||||
double magnitude(); // This will call Vector_magnitude()
|
||||
...
|
||||
}
|
||||
} Vector;
|
||||
</pre>
|
||||
|
|
@ -2958,7 +2959,7 @@ char *Person_name_get(Person *p) {
|
|||
}
|
||||
|
||||
void Person_name_set(Person *p, char *val) {
|
||||
strncpy(p->name,val,50);
|
||||
strncpy(p->name, val, 50);
|
||||
make_upper(p->name);
|
||||
}
|
||||
%}
|
||||
|
|
@ -3083,7 +3084,7 @@ in terms of high-level accessor functions such as this,
|
|||
<div class="code">
|
||||
<pre>
|
||||
double Vector_x_get(Vector *v) {
|
||||
return v->x;
|
||||
return v->x;
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3100,15 +3101,15 @@ the following function is generated instead:
|
|||
static int
|
||||
_wrap_Vector_x_get(ClientData clientData, Tcl_Interp *interp,
|
||||
int objc, Tcl_Obj *CONST objv[]) {
|
||||
struct Vector *arg1 ;
|
||||
double result ;
|
||||
|
||||
if (SWIG_GetArgs(interp, objc, objv,"p:Vector_x_get self ",&arg0,
|
||||
SWIGTYPE_p_Vector) == TCL_ERROR)
|
||||
return TCL_ERROR;
|
||||
result = (double ) (arg1->x);
|
||||
Tcl_SetObjResult(interp,Tcl_NewDoubleObj((double) result));
|
||||
return TCL_OK;
|
||||
struct Vector *arg1 ;
|
||||
double result ;
|
||||
|
||||
if (SWIG_GetArgs(interp, objc, objv, "p:Vector_x_get self ", &arg0,
|
||||
SWIGTYPE_p_Vector) == TCL_ERROR)
|
||||
return TCL_ERROR;
|
||||
result = (double ) (arg1->x);
|
||||
Tcl_SetObjResult(interp, Tcl_NewDoubleObj((double) result));
|
||||
return TCL_OK;
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3139,9 +3140,9 @@ output of SWIG is structured first.</p>
|
|||
|
||||
|
||||
<p>
|
||||
When SWIG creates its output file, it is broken up into five sections
|
||||
When SWIG creates its output C/C++ file, it is broken up into five sections
|
||||
corresponding to runtime code, headers, wrapper functions, and module
|
||||
initialization code (in that order).
|
||||
initialization code (in that order).
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
|
|
@ -3175,31 +3176,59 @@ the module upon loading.
|
|||
|
||||
|
||||
<p>
|
||||
Code is inserted into the appropriate code section by using one
|
||||
of the code insertion directives listed below. The order of the sections in
|
||||
the wrapper file is as shown:
|
||||
The <tt>%insert</tt> directive enables inserting blocks of code into a given section of the generated code.
|
||||
It can be used in one of two ways:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%insert("section") "filename"
|
||||
%insert("section") %{ ... %}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
The first will dump the contents of the file in the given <tt>filename</tt> into the named <tt>section</tt>.
|
||||
The second inserts the code between the braces into the named <tt>section</tt>.
|
||||
For example, the following adds code into the runtime section:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%insert("runtime") %{
|
||||
... code in runtime section ...
|
||||
%}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
There are the 5 sections, however, some target languages add in additional sections and some of these result in code being generated into a target language file instead of the C/C++ wrapper file.
|
||||
These are documented when available in the target language chapters.
|
||||
Macros named after the code sections are available as additional directives and these macro directives are normally used instead of <tt>%insert</tt>.
|
||||
For example, <tt>%runtime</tt> is used instead of <tt>%insert("runtime")</tt>.
|
||||
The valid sections and order of the sections in the generated C/C++ wrapper file is as shown:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%begin %{
|
||||
... code in begin section ...
|
||||
... code in begin section ...
|
||||
%}
|
||||
|
||||
%runtime %{
|
||||
... code in runtime section ...
|
||||
... code in runtime section ...
|
||||
%}
|
||||
|
||||
%header %{
|
||||
... code in header section ...
|
||||
... code in header section ...
|
||||
%}
|
||||
|
||||
%wrapper %{
|
||||
... code in wrapper section ...
|
||||
... code in wrapper section ...
|
||||
%}
|
||||
|
||||
%init %{
|
||||
... code in init section ...
|
||||
... code in init section ...
|
||||
%}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3441,7 +3470,7 @@ header files.
|
|||
<p>
|
||||
Sometimes, it is necessary to use certain header files in order for
|
||||
the code generated by SWIG to compile properly. Make sure you
|
||||
include certain header files by using a <tt>%{,%}</tt> block like this:
|
||||
include certain header files by using a <tt>%{ %}</tt> block like this:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -304,6 +304,11 @@ The following table lists the Scilab specific command line options in addition t
|
|||
<td>Generate the gateway XML with the given <gateway_id></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><tt>-targetversion</tt></td>
|
||||
<td>Generate for Scilab target (major) version</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
<p>
|
||||
|
|
@ -331,13 +336,17 @@ There are a few exceptions, such as constants and enumerations, which can be wra
|
|||
|
||||
|
||||
<p>
|
||||
In Scilab 5.x, identifier names are composed of 24 characters maximum (this limitation should disappear from Scilab 6.0 onwards).
|
||||
<br>Thus long function or variable names may be truncated and this can cause ambiguities.
|
||||
In Scilab 5.x, identifier names are composed of 24 characters maximum (this limitation disappears from Scilab 6.0 onwards).
|
||||
<br>By default, variable, member, and function names longer than 24 charaters are truncated, and a warning is produced for each truncation.
|
||||
</p>
|
||||
<p>This happens especially when wrapping structs/classes, for which the wrapped function name is composed of the struct/class name and field names.
|
||||
<p>This can cause ambiguities, especially when wrapping structs/classes, for which the wrapped function name is composed of the struct/class name and field names.
|
||||
In these cases, the <a href="SWIG.html#SWIG_rename_ignore">%rename directive</a> can be used to choose a different Scilab name.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Note: truncations can be disabled by specifying the target version 6 of Scilab in the <tt>targetversion</tt> argument (i.e. <tt>-targetversion 6</tt>).
|
||||
</p>
|
||||
|
||||
<H3><a name="Scilab_wrapping_functions">39.3.3 Functions</a></H3>
|
||||
|
||||
|
||||
|
|
@ -443,14 +452,15 @@ The example below shows this for a C function returning 2 values and a result:
|
|||
int divide(int n, int d, int *OUTPUT, int *OUTPUT);
|
||||
|
||||
%{
|
||||
int divide(int n, int d, int q*, int *r) {
|
||||
if (d != 0) {
|
||||
*q = n / d;
|
||||
*r = n % d;
|
||||
return 1;
|
||||
}
|
||||
else return 0;
|
||||
}
|
||||
int divide(int n, int d, int q*, int *r) {
|
||||
if (d != 0) {
|
||||
*q = n / d;
|
||||
*r = n % d;
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
%}
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -1123,7 +1133,7 @@ But we can use either use the <tt>get_perimeter()</tt> function of the parent cl
|
|||
|
||||
|
||||
<p>
|
||||
As explained in <a href="http://www.swig.org/Doc3.0/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">6.15</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>:
|
||||
|
|
@ -1242,7 +1252,7 @@ struct triplet {
|
|||
}
|
||||
};
|
||||
|
||||
%template(IntTriplet) triplet<int,int,int>;
|
||||
%template(IntTriplet) triplet<int, int, int>;
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
|
|
@ -1320,7 +1330,7 @@ private:
|
|||
<div class="targetlang"><pre>
|
||||
--> c1 = new_Complex(3, 7);
|
||||
|
||||
--> c2 = Complex_plus(c, new_Complex(1,1));
|
||||
--> c2 = Complex_plus(c, new_Complex(1, 1));
|
||||
|
||||
--> Complex_toDouble(c2)
|
||||
ans =
|
||||
|
|
@ -1354,7 +1364,7 @@ namespace foo {
|
|||
}
|
||||
|
||||
struct Vector {
|
||||
double x,y,z;
|
||||
double x, y, z;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -1635,17 +1645,17 @@ double **create_matrix() {
|
|||
return M;
|
||||
}
|
||||
|
||||
// Gets the item M(i,j) value
|
||||
// Gets the item M(i, j) value
|
||||
double get_matrix(double **M, int i, int j) {
|
||||
return M[i][j];
|
||||
}
|
||||
|
||||
// Sets the item M(i,j) value to be val
|
||||
// Sets the item M(i, j) value to be val
|
||||
void set_matrix(double **M, int i, int j, double val) {
|
||||
M[i][j] = val;
|
||||
}
|
||||
|
||||
// Prints a matrix (2,2) to console
|
||||
// Prints a matrix (2, 2) to console
|
||||
void print_matrix(double **M, int nbRows, int nbCols) {
|
||||
int i, j;
|
||||
for (i = 0; i < 2; i++) {
|
||||
|
|
@ -1768,7 +1778,7 @@ void absolute(int *matrix, int matrixNbRow, int matrixNbCol,
|
|||
The remarks made earlier for arrays also apply here:
|
||||
</p>
|
||||
<ul>
|
||||
<li>The values of matrices in Scilab are column-major orderered,</li>
|
||||
<li>The values of matrices in Scilab are column-major orderered, </li>
|
||||
<li>There is no control while converting <tt>double</tt> values to integers, <tt>double</tt> values are truncated without any checking or warning.</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -2061,7 +2071,7 @@ The command is:
|
|||
</p>
|
||||
|
||||
<div class="shell"><pre>
|
||||
$ swig -scilab -builder -buildercflags -I/opt/foo/include -builderldflags "-L/opt/foo/lib -lfoo" -buildersources baa1.cxx,baa2.cxx example.i
|
||||
$ swig -scilab -builder -buildercflags -I/opt/foo/include -builderldflags "-L/opt/foo/lib -lfoo" -buildersources baa1.cxx, baa2.cxx example.i
|
||||
</pre></div>
|
||||
|
||||
<H2><a name="Scilab_generated_scripts">39.7 Generated scripts</a></H2>
|
||||
|
|
@ -2081,12 +2091,12 @@ In this part we give some details about the generated Scilab scripts.
|
|||
ilib_name = "examplelib";
|
||||
files = ["example_wrap.c"];
|
||||
libs = [];
|
||||
table = ["fact","_wrap_fact";"Foo_set","_wrap_Foo_set";"Foo_get","_wrap_Foo_get";];
|
||||
ilib_build(ilib_name,table,files,libs);
|
||||
table = ["fact", "_wrap_fact";"Foo_set", "_wrap_Foo_set";"Foo_get", "_wrap_Foo_get";];
|
||||
ilib_build(ilib_name, table, files, libs);
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
<tt>ilib_build(lib_name,table,files,libs)</tt> is used to create shared libraries, and to generate a loader file used to dynamically load the shared library into Scilab.
|
||||
<tt>ilib_build(lib_name, table, files, libs)</tt> is used to create shared libraries, and to generate a loader file used to dynamically load the shared library into Scilab.
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
|
|
@ -2117,7 +2127,7 @@ list_functions = [ 'fact';
|
|||
'Foo_set';
|
||||
'Foo_get';
|
||||
];
|
||||
addinter(libexamplelib_path+'/libexamplelib.so','libexamplelib',list_functions);
|
||||
addinter(libexamplelib_path+'/libexamplelib.so', 'libexamplelib', list_functions);
|
||||
// remove temp. variables on stack
|
||||
clear libexamplelib_path;
|
||||
clear list_functions;
|
||||
|
|
@ -2126,7 +2136,7 @@ clear get_file_path;
|
|||
</pre></div>
|
||||
|
||||
<p>
|
||||
<tt>addinter(files,spname,fcts)</tt> performs dynamic linking of a compiled C interface function.
|
||||
<tt>addinter(files, spname, fcts)</tt> performs dynamic linking of a compiled C interface function.
|
||||
</p>
|
||||
<ul>
|
||||
<li><tt><b>files</b></tt>: a character string or a vector of character strings defining the object files (containing the C interface functions) to link with.</li>
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ int wrap_fact(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
|
|||
}
|
||||
arg0 = atoi(argv[1]);
|
||||
result = fact(arg0);
|
||||
sprintf(interp->result,"%d", result);
|
||||
sprintf(interp->result, "%d", result);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
|
|
@ -247,7 +247,7 @@ representation of a structure. For example,
|
|||
struct Vector {
|
||||
Vector();
|
||||
~Vector();
|
||||
double x,y,z;
|
||||
double x, y, z;
|
||||
};
|
||||
|
||||
</pre></div>
|
||||
|
|
@ -302,7 +302,7 @@ class Vector {
|
|||
public:
|
||||
Vector();
|
||||
~Vector();
|
||||
double x,y,z;
|
||||
double x, y, z;
|
||||
};
|
||||
</pre></div>
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
<H1><a name="Sections">SWIG-3.0 Documentation</a></H1>
|
||||
|
||||
<p>
|
||||
Last update : SWIG-3.0.10 (in progress)
|
||||
Last update : SWIG-4.0.0 (in progress)
|
||||
</p>
|
||||
|
||||
<H2><a name="Sections_Sections">Sections</a></H2>
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ SWIG tries to guess the right options when it is installed. Therefore,
|
|||
you may want to start with one of the examples in the <tt>SWIG/Examples/tcl</tt>
|
||||
directory. If that doesn't work, you will need to read the man-pages for
|
||||
your compiler and linker to get the right set of options. You might also
|
||||
check the <a href="http://www.dabeaz.com/cgi-bin/wiki.pl">SWIG Wiki</a> for
|
||||
check the <a href="https://github.com/swig/swig/wiki">SWIG Wiki</a> for
|
||||
additional information.
|
||||
</p>
|
||||
|
||||
|
|
@ -837,8 +837,8 @@ access constants in procedure bodies. For example:
|
|||
<div class="code">
|
||||
<pre>
|
||||
proc blah {} {
|
||||
global FOO
|
||||
bar $FOO
|
||||
global FOO
|
||||
bar $FOO
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -865,7 +865,7 @@ its actual value or a symbolic identifier name. For example:
|
|||
<div class="code">
|
||||
<pre>
|
||||
proc blah {} {
|
||||
bar FOO
|
||||
bar FOO
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -949,12 +949,12 @@ example:
|
|||
%inline %{
|
||||
/* C-style cast */
|
||||
Bar *FooToBar(Foo *f) {
|
||||
return (Bar *) f;
|
||||
return (Bar *) f;
|
||||
}
|
||||
|
||||
/* C++-style cast */
|
||||
Foo *BarToFoo(Bar *b) {
|
||||
return dynamic_cast<Foo*>(b);
|
||||
return dynamic_cast<Foo*>(b);
|
||||
}
|
||||
|
||||
Foo *IncrFoo(Foo *f, int i) {
|
||||
|
|
@ -981,7 +981,7 @@ This provides a very natural interface. For example,
|
|||
|
||||
<div class="code"><pre>
|
||||
struct Vector {
|
||||
double x,y,z;
|
||||
double x, y, z;
|
||||
};
|
||||
|
||||
</pre></div>
|
||||
|
|
@ -1028,12 +1028,12 @@ can also be forced to be read-only using the <tt>%immutable</tt> directive. For
|
|||
<div class="code">
|
||||
<pre>
|
||||
struct Foo {
|
||||
...
|
||||
%immutable;
|
||||
int x; /* Read-only members */
|
||||
char *name;
|
||||
%mutable;
|
||||
...
|
||||
...
|
||||
%immutable;
|
||||
int x; /* Read-only members */
|
||||
char *name;
|
||||
%mutable;
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1100,11 +1100,11 @@ pointer. For example, suppose you have two structures like this:
|
|||
<div class="code">
|
||||
<pre>
|
||||
struct Foo {
|
||||
int a;
|
||||
int a;
|
||||
};
|
||||
|
||||
struct Bar {
|
||||
Foo f;
|
||||
Foo f;
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1302,9 +1302,8 @@ To illustrate, suppose you have a class like this:
|
|||
<pre>
|
||||
class Spam {
|
||||
public:
|
||||
static void foo();
|
||||
static int bar;
|
||||
|
||||
static void foo();
|
||||
static int bar;
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1662,10 +1661,10 @@ submodules or packages. For example, if you have a file like this,
|
|||
%module example
|
||||
|
||||
namespace foo {
|
||||
int fact(int n);
|
||||
struct Vector {
|
||||
double x,y,z;
|
||||
};
|
||||
int fact(int n);
|
||||
struct Vector {
|
||||
double x, y, z;
|
||||
};
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1731,16 +1730,16 @@ For example:
|
|||
|
||||
template<class T1, class T2>
|
||||
struct pair {
|
||||
typedef T1 first_type;
|
||||
typedef T2 second_type;
|
||||
T1 first;
|
||||
T2 second;
|
||||
pair();
|
||||
pair(const T1&, const T2&);
|
||||
typedef T1 first_type;
|
||||
typedef T2 second_type;
|
||||
T1 first;
|
||||
T2 second;
|
||||
pair();
|
||||
pair(const T1&, const T2&);
|
||||
~pair();
|
||||
};
|
||||
|
||||
%template(pairii) pair<int,int>;
|
||||
%template(pairii) pair<int, int>;
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -1776,9 +1775,9 @@ that implements <tt>operator->()</tt> like this:
|
|||
<div class="code">
|
||||
<pre>
|
||||
template<class T> class SmartPtr {
|
||||
...
|
||||
T *operator->();
|
||||
...
|
||||
...
|
||||
T *operator->();
|
||||
...
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1791,8 +1790,8 @@ Then, if you have a class like this,
|
|||
<pre>
|
||||
class Foo {
|
||||
public:
|
||||
int x;
|
||||
int bar();
|
||||
int x;
|
||||
int bar();
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1874,9 +1873,9 @@ have a class like this
|
|||
<pre>
|
||||
class Foo {
|
||||
public:
|
||||
int x;
|
||||
int spam(int);
|
||||
...
|
||||
int x;
|
||||
int spam(int);
|
||||
...
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -2065,10 +2064,10 @@ change the ownership of an object. For instance, consider code like this:
|
|||
<div class="code">
|
||||
<pre>
|
||||
class Node {
|
||||
Object *value;
|
||||
Object *value;
|
||||
public:
|
||||
void set_value(Object *v) { value = v; }
|
||||
...
|
||||
void set_value(Object *v) { value = v; }
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2125,7 +2124,7 @@ example:
|
|||
<div class="code">
|
||||
<pre>
|
||||
void add(int x, int y, int *result) {
|
||||
*result = x + y;
|
||||
*result = x + y;
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2137,7 +2136,7 @@ or perhaps
|
|||
<div class="code">
|
||||
<pre>
|
||||
int sub(int *x, int *y) {
|
||||
return *x+*y;
|
||||
return *x+*y;
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2198,7 +2197,7 @@ If a function mutates one of its parameters like this,
|
|||
<div class="code">
|
||||
<pre>
|
||||
void negate(int *x) {
|
||||
*x = -(*x);
|
||||
*x = -(*x);
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2328,7 +2327,7 @@ class DoubleArray {
|
|||
}
|
||||
// Destroy an array
|
||||
~DoubleArray() {
|
||||
delete ptr;
|
||||
delete ptr;
|
||||
}
|
||||
// Return the length of the array
|
||||
int length() {
|
||||
|
|
@ -2466,9 +2465,9 @@ you might define a typemap like this:
|
|||
%module example
|
||||
|
||||
%typemap(in) int {
|
||||
if (Tcl_GetIntFromObj(interp,$input,&$1) == TCL_ERROR)
|
||||
if (Tcl_GetIntFromObj(interp, $input, &$1) == TCL_ERROR)
|
||||
return TCL_ERROR;
|
||||
printf("Received an integer : %d\n",$1);
|
||||
printf("Received an integer : %d\n", $1);
|
||||
}
|
||||
%inline %{
|
||||
extern int fact(int n);
|
||||
|
|
@ -2505,9 +2504,9 @@ You can refine this by supplying an optional parameter name. For example:
|
|||
%module example
|
||||
|
||||
%typemap(in) int n {
|
||||
if (Tcl_GetIntFromObj(interp,$input,&$1) == TCL_ERROR)
|
||||
if (Tcl_GetIntFromObj(interp, $input, &$1) == TCL_ERROR)
|
||||
return TCL_ERROR;
|
||||
printf("n = %d\n",$1);
|
||||
printf("n = %d\n", $1);
|
||||
}
|
||||
%inline %{
|
||||
extern int fact(int n);
|
||||
|
|
@ -2529,9 +2528,9 @@ the typemap system follows <tt>typedef</tt> declarations. For example:
|
|||
<div class="code">
|
||||
<pre>
|
||||
%typemap(in) int n {
|
||||
if (Tcl_GetIntFromObj(interp,$input,&$1) == TCL_ERROR)
|
||||
if (Tcl_GetIntFromObj(interp, $input, &$1) == TCL_ERROR)
|
||||
return TCL_ERROR;
|
||||
printf("n = %d\n",$1);
|
||||
printf("n = %d\n", $1);
|
||||
}
|
||||
%inline %{
|
||||
typedef int Integer;
|
||||
|
|
@ -2553,7 +2552,7 @@ Typemaps can also be defined for groups of consecutive arguments. For example:
|
|||
<div class="code">
|
||||
<pre>
|
||||
%typemap(in) (char *str, int len) {
|
||||
$1 = Tcl_GetStringFromObj($input,&$2);
|
||||
$1 = Tcl_GetStringFromObj($input, &$2);
|
||||
};
|
||||
|
||||
int count(char c, char *str, int len);
|
||||
|
|
@ -2586,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>
|
||||
|
|
@ -2797,36 +2796,36 @@ used as a <tt>char **</tt> object.
|
|||
|
||||
// This tells SWIG to treat char ** as a special case
|
||||
%typemap(in) char ** {
|
||||
Tcl_Obj **listobjv;
|
||||
int nitems;
|
||||
int i;
|
||||
if (Tcl_ListObjGetElements(interp, $input, &nitems, &listobjv) == TCL_ERROR) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
$1 = (char **) malloc((nitems+1)*sizeof(char *));
|
||||
for (i = 0; i < nitems; i++) {
|
||||
$1[i] = Tcl_GetStringFromObj(listobjv[i],0);
|
||||
}
|
||||
$1[i] = 0;
|
||||
Tcl_Obj **listobjv;
|
||||
int nitems;
|
||||
int i;
|
||||
if (Tcl_ListObjGetElements(interp, $input, &nitems, &listobjv) == TCL_ERROR) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
$1 = (char **) malloc((nitems+1)*sizeof(char *));
|
||||
for (i = 0; i < nitems; i++) {
|
||||
$1[i] = Tcl_GetStringFromObj(listobjv[i], 0);
|
||||
}
|
||||
$1[i] = 0;
|
||||
}
|
||||
|
||||
// This gives SWIG some cleanup code that will get called after the function call
|
||||
%typemap(freearg) char ** {
|
||||
if ($1) {
|
||||
free($1);
|
||||
}
|
||||
if ($1) {
|
||||
free($1);
|
||||
}
|
||||
}
|
||||
|
||||
// Now a test functions
|
||||
%inline %{
|
||||
int print_args(char **argv) {
|
||||
int print_args(char **argv) {
|
||||
int i = 0;
|
||||
while (argv[i]) {
|
||||
printf("argv[%d] = %s\n", i,argv[i]);
|
||||
i++;
|
||||
printf("argv[%d] = %s\n", i, argv[i]);
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
}
|
||||
%}
|
||||
%include "tclsh.i"
|
||||
|
||||
|
|
@ -2855,21 +2854,21 @@ function argument. For example :
|
|||
<div class="code"><pre>
|
||||
// A typemap defining how to return an argument by appending it to the result
|
||||
%typemap(argout) double *outvalue {
|
||||
Tcl_Obj *o = Tcl_NewDoubleObj($1);
|
||||
Tcl_ListObjAppendElement(interp,$result,o);
|
||||
Tcl_Obj *o = Tcl_NewDoubleObj($1);
|
||||
Tcl_ListObjAppendElement(interp, $result, o);
|
||||
}
|
||||
|
||||
// A typemap telling SWIG to ignore an argument for input
|
||||
// However, we still need to pass a pointer to the C function
|
||||
%typemap(in,numinputs=0) double *outvalue (double temp) {
|
||||
$1 = &temp;
|
||||
%typemap(in, numinputs=0) double *outvalue (double temp) {
|
||||
$1 = &temp;
|
||||
}
|
||||
|
||||
// Now a function returning two values
|
||||
int mypow(double a, double b, double *outvalue) {
|
||||
if ((a < 0) || (b < 0)) return -1;
|
||||
*outvalue = pow(a,b);
|
||||
return 0;
|
||||
if ((a < 0) || (b < 0)) return -1;
|
||||
*outvalue = pow(a, b);
|
||||
return 0;
|
||||
};
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -2992,7 +2991,7 @@ work)
|
|||
<div class="code">
|
||||
<pre>
|
||||
%typemap(out) int, short, long {
|
||||
Tcl_SetIntObj($result,(int) $1);
|
||||
Tcl_SetIntObj($result, (int) $1);
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3004,10 +3003,10 @@ work)
|
|||
<div class="code">
|
||||
<pre>
|
||||
%typemap(in) float, double {
|
||||
double temp;
|
||||
if (Tcl_GetDoubleFromObj(interp, $input, &temp) == TCL_ERROR)
|
||||
return TCL_ERROR;
|
||||
$1 = ($1_ltype) temp;
|
||||
double temp;
|
||||
if (Tcl_GetDoubleFromObj(interp, $input, &temp) == TCL_ERROR)
|
||||
return TCL_ERROR;
|
||||
$1 = ($1_ltype) temp;
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3017,7 +3016,7 @@ work)
|
|||
<div class="code">
|
||||
<pre>
|
||||
%typemap(out) float, double {
|
||||
Tcl_SetDoubleObj($result, $1);
|
||||
Tcl_SetDoubleObj($result, $1);
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3029,9 +3028,8 @@ work)
|
|||
<div class="code">
|
||||
<pre>
|
||||
%typemap(in) char * {
|
||||
int len;
|
||||
$1 = Tcl_GetStringFromObj(interp, &len);
|
||||
}
|
||||
int len;
|
||||
$1 = Tcl_GetStringFromObj(interp, &len);
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3040,8 +3038,8 @@ work)
|
|||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%typemap(out,noblock=1,fragment="SWIG_FromCharPtr") char *, const char * {
|
||||
Tcl_SetObjResult(interp,SWIG_FromCharPtr((const char *)$1));
|
||||
%typemap(out, noblock=1, fragment="SWIG_FromCharPtr") char *, const char * {
|
||||
Tcl_SetObjResult(interp, SWIG_FromCharPtr((const char *)$1));
|
||||
}
|
||||
|
||||
</pre>
|
||||
|
|
@ -3090,7 +3088,9 @@ is usually accessed as follows:
|
|||
<div class="indent">
|
||||
<pre>
|
||||
Foo *f;
|
||||
if (SWIG_ConvertPtr($input, (void **) &f, SWIGTYPE_p_Foo, 0) == -1) return NULL;
|
||||
if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &f, SWIGTYPE_p_Foo, 0))) {
|
||||
SWIG_exception_fail(SWIG_TypeError, "in method '$symname', expecting type Foo");
|
||||
}
|
||||
|
||||
Tcl_Obj *;
|
||||
obj = SWIG_NewPointerObj(f, SWIGTYPE_p_Foo, 0);
|
||||
|
|
@ -3105,7 +3105,9 @@ variable <tt>$1_descriptor</tt>. For example:
|
|||
<div class="indent">
|
||||
<pre>
|
||||
%typemap(in) Foo * {
|
||||
if ((SWIG_ConvertPtr($input,(void **) &$1, $1_descriptor,0)) == -1) return NULL;
|
||||
if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor, 0))) {
|
||||
SWIG_exception_fail(SWIG_TypeError, "in method '$symname', expecting type Foo");
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3118,7 +3120,9 @@ For example:
|
|||
<div class="indent">
|
||||
<pre>
|
||||
%typemap(in) Foo * {
|
||||
if ((SWIG_ConvertPtr($input,(void **) &$1, $descriptor(Foo *), 0)) == -1) return NULL;
|
||||
if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &$1, $descriptor(Foo *), 0))) {
|
||||
SWIG_exception_fail(SWIG_TypeError, "in method '$symname', expecting type Foo");
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -95,7 +95,7 @@ int execlp(const char *path, const char *arg1, ...);
|
|||
...
|
||||
|
||||
/* Example */
|
||||
execlp("ls","ls","-l",NULL);
|
||||
execlp("ls", "ls", "-l", NULL);
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -126,16 +126,16 @@ example:
|
|||
<div class="code">
|
||||
<pre>
|
||||
List make_list(const char *s, ...) {
|
||||
va_list ap;
|
||||
List x;
|
||||
...
|
||||
va_start(ap, s);
|
||||
while (s) {
|
||||
x.append(s);
|
||||
s = va_arg(ap, const char *);
|
||||
}
|
||||
va_end(ap);
|
||||
return x;
|
||||
va_list ap;
|
||||
List x;
|
||||
...
|
||||
va_start(ap, s);
|
||||
while (s) {
|
||||
x.append(s);
|
||||
s = va_arg(ap, const char *);
|
||||
}
|
||||
va_end(ap);
|
||||
return x;
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -188,12 +188,12 @@ In contrast, suppose you attempted to make some kind of wrapper around
|
|||
<div class="code">
|
||||
<pre>
|
||||
int wrap_printf(const char *fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap,fmt);
|
||||
...
|
||||
printf(fmt,ap);
|
||||
...
|
||||
va_end(ap);
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
...
|
||||
printf(fmt, ap);
|
||||
...
|
||||
va_end(ap);
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -471,15 +471,15 @@ like this:
|
|||
<div class="code">
|
||||
<pre>
|
||||
wrap_printf() {
|
||||
char *arg1;
|
||||
void *arg2;
|
||||
int result;
|
||||
char *arg1;
|
||||
void *arg2;
|
||||
int result;
|
||||
|
||||
arg1 = "%s";
|
||||
arg2 = (void *) PyString_AsString(arg2obj);
|
||||
...
|
||||
result = printf(arg1,arg2);
|
||||
...
|
||||
arg1 = "%s";
|
||||
arg2 = (void *) PyString_AsString(arg2obj);
|
||||
...
|
||||
result = printf(arg1, arg2);
|
||||
...
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -517,7 +517,7 @@ like this:
|
|||
argc = PyTuple_Size(varargs);
|
||||
if (argc > 10) {
|
||||
PyErr_SetString(PyExc_ValueError, "Too many arguments");
|
||||
return NULL;
|
||||
SWIG_fail;
|
||||
}
|
||||
for (i = 0; i < argc; i++) {
|
||||
PyObject *pyobj = PyTuple_GetItem(varargs, i);
|
||||
|
|
@ -525,16 +525,16 @@ like this:
|
|||
%#if PY_VERSION_HEX>=0x03000000
|
||||
PyObject *pystr;
|
||||
if (!PyUnicode_Check(pyobj)) {
|
||||
PyErr_SetString(PyExc_ValueError, "Expected a string");
|
||||
return NULL;
|
||||
PyErr_SetString(PyExc_ValueError, "Expected a string");
|
||||
SWIG_fail;
|
||||
}
|
||||
pystr = PyUnicode_AsUTF8String(pyobj);
|
||||
str = strdup(PyBytes_AsString(pystr));
|
||||
Py_XDECREF(pystr);
|
||||
%#else
|
||||
if (!PyString_Check(pyobj)) {
|
||||
PyErr_SetString(PyExc_ValueError, "Expected a string");
|
||||
return NULL;
|
||||
PyErr_SetString(PyExc_ValueError, "Expected a string");
|
||||
SWIG_fail;
|
||||
}
|
||||
str = PyString_AsString(pyobj);
|
||||
%#endif
|
||||
|
|
@ -626,23 +626,23 @@ example. For example:
|
|||
of strings */
|
||||
|
||||
%typemap(in) (...) {
|
||||
char **argv;
|
||||
int argc;
|
||||
int i;
|
||||
char **argv;
|
||||
int argc;
|
||||
int i;
|
||||
|
||||
argc = PyTuple_Size(varargs);
|
||||
argv = (char **) malloc(sizeof(char *)*(argc+1));
|
||||
for (i = 0; i < argc; i++) {
|
||||
PyObject *o = PyTuple_GetItem(varargs,i);
|
||||
if (!PyString_Check(o)) {
|
||||
PyErr_SetString(PyExc_ValueError,"Expected a string");
|
||||
free(argv);
|
||||
return NULL;
|
||||
}
|
||||
argv[i] = PyString_AsString(o);
|
||||
}
|
||||
argv[i] = NULL;
|
||||
$1 = (void *) argv;
|
||||
argc = PyTuple_Size(varargs);
|
||||
argv = (char **) malloc(sizeof(char *)*(argc+1));
|
||||
for (i = 0; i < argc; i++) {
|
||||
PyObject *o = PyTuple_GetItem(varargs, i);
|
||||
if (!PyString_Check(o)) {
|
||||
free(argv);
|
||||
PyErr_SetString(PyExc_ValueError, "Expected a string");
|
||||
SWIG_fail;
|
||||
}
|
||||
argv[i] = PyString_AsString(o);
|
||||
}
|
||||
argv[i] = NULL;
|
||||
$1 = (void *) argv;
|
||||
}
|
||||
|
||||
/* Rewrite the function call, using libffi */
|
||||
|
|
@ -676,11 +676,11 @@ example. For example:
|
|||
&ffi_type_uint, types) == FFI_OK) {
|
||||
ffi_call(&cif, (void (*)()) execlp, &result, values);
|
||||
} else {
|
||||
PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!");
|
||||
free(types);
|
||||
free(values);
|
||||
free(arg3);
|
||||
return NULL;
|
||||
PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!");
|
||||
SWIG_fail;
|
||||
}
|
||||
free(types);
|
||||
free(values);
|
||||
|
|
@ -733,7 +733,7 @@ As a more extreme example of libffi, here is some code that attempts to wrap <tt
|
|||
argc = PyTuple_Size(varargs);
|
||||
argv = (vtype *) malloc(argc*sizeof(vtype));
|
||||
for (i = 0; i < argc; i++) {
|
||||
PyObject *o = PyTuple_GetItem(varargs,i);
|
||||
PyObject *o = PyTuple_GetItem(varargs, i);
|
||||
if (PyInt_Check(o)) {
|
||||
argv[i].type = VT_INT;
|
||||
argv[i].val.ivalue = PyInt_AsLong(o);
|
||||
|
|
@ -744,8 +744,8 @@ As a more extreme example of libffi, here is some code that attempts to wrap <tt
|
|||
argv[i].type = VT_POINTER;
|
||||
argv[i].val.pvalue = (void *) PyString_AsString(o);
|
||||
} else {
|
||||
PyErr_SetString(PyExc_ValueError,"Unsupported argument type");
|
||||
free(argv);
|
||||
PyErr_SetString(PyExc_ValueError, "Unsupported argument type");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
|
@ -793,11 +793,11 @@ As a more extreme example of libffi, here is some code that attempts to wrap <tt
|
|||
&ffi_type_uint, types) == FFI_OK) {
|
||||
ffi_call(&cif, (void (*)()) printf, &result, values);
|
||||
} else {
|
||||
PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!");
|
||||
free(types);
|
||||
free(values);
|
||||
free(args);
|
||||
return NULL;
|
||||
PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!");
|
||||
SWIG_fail;
|
||||
}
|
||||
free(types);
|
||||
free(values);
|
||||
|
|
@ -912,12 +912,12 @@ and it fully supports classes much like the <tt>%rename</tt> directive. For exa
|
|||
|
||||
class Foo {
|
||||
public:
|
||||
virtual void bar(char *arg, ...); // gets varargs above
|
||||
virtual void bar(char *arg, ...); // gets varargs above
|
||||
};
|
||||
|
||||
class Spam: public Foo {
|
||||
public:
|
||||
virtual void bar(char *arg, ...); // gets varargs above
|
||||
virtual void bar(char *arg, ...); // gets varargs above
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -952,9 +952,9 @@ are placed in <tt>arg2</tt>, <tt>arg3</tt>, and so forth. For example:
|
|||
<div class="code">
|
||||
<pre>
|
||||
%feature("action") Foo::bar {
|
||||
...
|
||||
result = arg1->bar(arg2, arg3, etc.);
|
||||
...
|
||||
...
|
||||
result = arg1->bar(arg2, arg3, etc.);
|
||||
...
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -987,10 +987,10 @@ you might structure your interface like this:
|
|||
<div class="code">
|
||||
<pre>
|
||||
%typemap(const char *fmt, ...) {
|
||||
...
|
||||
...
|
||||
}
|
||||
%feature("action") traceprintf {
|
||||
...
|
||||
...
|
||||
}
|
||||
|
||||
/* Include some header file with traceprintf in it */
|
||||
|
|
@ -1011,7 +1011,7 @@ to control this:
|
|||
<pre>
|
||||
#ifdef USE_LIBFFI
|
||||
%feature("action") printf {
|
||||
...
|
||||
...
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_OTHERFFI
|
||||
|
|
|
|||
|
|
@ -112,16 +112,16 @@ suppress a warning for a method in a class hierarchy, you could do this:
|
|||
%warnfilter(501) Object::foo;
|
||||
class Object {
|
||||
public:
|
||||
int foo(int);
|
||||
int foo(double); // Silently ignored
|
||||
...
|
||||
int foo(int);
|
||||
int foo(double); // Silently ignored
|
||||
...
|
||||
};
|
||||
|
||||
class Derived : public Object {
|
||||
public:
|
||||
int foo(int);
|
||||
int foo(double); // Silently ignored
|
||||
...
|
||||
int foo(int);
|
||||
int foo(double); // Silently ignored
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -136,7 +136,7 @@ Warnings can be suppressed for an entire class by supplying a class name. For e
|
|||
|
||||
class Object {
|
||||
public:
|
||||
... // All 501 warnings ignored in class
|
||||
... // All 501 warnings ignored in class
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -259,7 +259,7 @@ Warning messages can be associated with typemaps using the
|
|||
<div class="code">
|
||||
<pre>
|
||||
%typemap(in, warning="901:You are really going to regret this usage of $1_type $1_name") blah * {
|
||||
...
|
||||
...
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -327,11 +327,11 @@ else
|
|||
endif
|
||||
PYTHON_SO = @PYTHON_SO@
|
||||
|
||||
# SWIG option for Python
|
||||
# SWIG option for Python3
|
||||
ifeq (,$(PY3))
|
||||
SWIGPYTHON = $(SWIG) -python
|
||||
SWIGOPTPY3 =
|
||||
else
|
||||
SWIGPYTHON = $(SWIG) -python -py3
|
||||
SWIGOPTPY3 = -py3
|
||||
endif
|
||||
|
||||
PEP8 = @PEP8@
|
||||
|
|
@ -342,7 +342,7 @@ PEP8_FLAGS = --ignore=E402,E501,E30,W291,W391
|
|||
# ----------------------------------------------------------------
|
||||
|
||||
python: $(SRCDIR_SRCS)
|
||||
$(SWIGPYTHON) $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
|
||||
$(SWIG) -python $(SWIGOPTPY3) $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
|
||||
$(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(ISRCS) $(SRCDIR_SRCS) $(INCLUDES) $(PYTHON_INCLUDE)
|
||||
$(LDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(PYTHON_DLNK) $(LIBS) -o $(LIBPREFIX)_$(TARGET)$(PYTHON_SO)
|
||||
|
||||
|
|
@ -351,7 +351,7 @@ python: $(SRCDIR_SRCS)
|
|||
# -----------------------------------------------------------------
|
||||
|
||||
python_cpp: $(SRCDIR_SRCS)
|
||||
$(SWIGPYTHON) -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
|
||||
$(SWIG) -python $(SWIGOPTPY3) -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
|
||||
$(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(INCLUDES) $(PYTHON_INCLUDE)
|
||||
$(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(PYTHON_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)_$(TARGET)$(PYTHON_SO)
|
||||
|
||||
|
|
@ -367,12 +367,12 @@ TKINTER =
|
|||
PYTHON_LIBOPTS = $(PYTHON_LINK) @LIBS@ $(TKINTER) $(SYSLIBS)
|
||||
|
||||
python_static: $(SRCDIR_SRCS)
|
||||
$(SWIGPYTHON) -lembed.i $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
|
||||
$(SWIG) -python $(SWIGOPTPY3) -lembed.i $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) @LINKFORSHARED@ $(ISRCS) $(SRCDIR_SRCS) $(INCLUDES) \
|
||||
$(PYTHON_INCLUDE) $(LIBS) -L$(PYTHON_LIB) $(PYTHON_LIBOPTS) -o $(TARGET)
|
||||
|
||||
python_static_cpp: $(SRCDIR_SRCS)
|
||||
$(SWIGPYTHON) -c++ -lembed.i $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
|
||||
$(SWIG) -python $(SWIGOPTPY3) -c++ -lembed.i $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(INCLUDES) \
|
||||
$(PYTHON_INCLUDE) $(LIBS) -L$(PYTHON_LIB) $(PYTHON_LIBOPTS) -o $(TARGET)
|
||||
|
||||
|
|
@ -896,10 +896,10 @@ mzscheme_clean:
|
|||
##### Ocaml #####
|
||||
##################################################################
|
||||
|
||||
OCC=@OCAMLC@
|
||||
OCAMLDLGEN=@OCAMLDLGEN@
|
||||
OCAMLFIND=@OCAMLFIND@
|
||||
OCAMLMKTOP=@OCAMLMKTOP@ $(SWIGWHERE)
|
||||
OCC=$(COMPILETOOL) @OCAMLC@
|
||||
OCAMLDLGEN=$(COMPILETOOL) @OCAMLDLGEN@
|
||||
OCAMLFIND=$(COMPILETOOL) @OCAMLFIND@
|
||||
OCAMLMKTOP=$(COMPILETOOL) @OCAMLMKTOP@ $(SWIGWHERE)
|
||||
NOLINK ?= false
|
||||
OCAMLPP= -pp "camlp4o ./swigp4.cmo"
|
||||
OCAMLP4WHERE=`$(COMPILETOOL) @CAMLP4@ -where`
|
||||
|
|
@ -910,8 +910,7 @@ OCAMLCORE=\
|
|||
$(SWIG) -ocaml -co swigp4.ml 2>/dev/null && \
|
||||
$(OCC) -c swig.mli && \
|
||||
$(OCC) -c swig.ml && \
|
||||
$(OCC) -I $(OCAMLP4WHERE) -pp "camlp4o pa_extend.cmo q_MLast.cmo" \
|
||||
-c swigp4.ml
|
||||
$(OCC) -I $(OCAMLP4WHERE) -pp "camlp4o pa_extend.cmo q_MLast.cmo" -c swigp4.ml
|
||||
|
||||
ocaml_static: $(SRCDIR_SRCS)
|
||||
$(OCAMLCORE)
|
||||
|
|
@ -919,32 +918,20 @@ ocaml_static: $(SRCDIR_SRCS)
|
|||
$(OCC) -g -c -ccopt -g -ccopt "$(INCLUDES)" $(ISRCS) $(SRCDIR_SRCS)
|
||||
$(OCC) -g -c $(INTERFACE:%.i=%.mli)
|
||||
$(OCC) -g -c $(INTERFACE:%.i=%.ml)
|
||||
test -z "$(PROGFILE)" || test -f "$(PROGFILE)" && \
|
||||
$(OCC) $(OCAMLPP) -c $(PROGFILE)
|
||||
$(NOLINK) || $(OCC) -g -ccopt -g -cclib -g -custom -o $(TARGET) \
|
||||
swig.cmo \
|
||||
$(INTERFACE:%.i=%.cmo) \
|
||||
$(PROGFILE:%.ml=%.cmo) \
|
||||
$(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) -cclib "$(LIBS)"
|
||||
test -z "$(PROGFILE)" || $(OCC) $(OCAMLPP) -c $(PROGFILE)
|
||||
$(NOLINK) || $(OCC) -g -ccopt -g -cclib -g -custom -o $(TARGET) swig.cmo $(INTERFACE:%.i=%.cmo) $(PROGFILE:%.ml=%.cmo) $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) -cclib "$(LIBS)"
|
||||
|
||||
ocaml_dynamic: $(SRCDIR_SRCS)
|
||||
$(OCAMLCORE)
|
||||
$(SWIG) -ocaml $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
|
||||
$(OCC) -g -c -ccopt -g -ccopt "$(INCLUDES)" $(ISRCS) $(SRCDIR_SRCS)
|
||||
$(CXXSHARED) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) $(CCSHARED) -o $(INTERFACE:%.i=%@SO@) \
|
||||
$(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) $(LIBS)
|
||||
$(OCAMLDLGEN) $(INTERFACE:%.i=%.ml) $(INTERFACE:%.i=%@SO@) > \
|
||||
$(INTERFACE:%.i=%_dynamic.ml)
|
||||
$(CXXSHARED) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) $(CCSHARED) -o $(INTERFACE:%.i=%@SO@) $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) $(LIBS)
|
||||
$(OCAMLDLGEN) $(INTERFACE:%.i=%.ml) $(INTERFACE:%.i=%@SO@) > $(INTERFACE:%.i=%_dynamic.ml)
|
||||
mv $(INTERFACE:%.i=%_dynamic.ml) $(INTERFACE:%.i=%.ml)
|
||||
rm $(INTERFACE:%.i=%.mli)
|
||||
$(OCAMLFIND) $(OCC) -g -c -package dl $(INTERFACE:%.i=%.ml)
|
||||
test -z "$(PROGFILE)" || test -f "$(PROGFILE)" && \
|
||||
$(OCC) $(OCAMLPP) -c $(PROGFILE)
|
||||
$(NOLINK) || $(OCAMLFIND) \
|
||||
$(OCC) -g -ccopt -g -cclib -g -custom -o $(TARGET) \
|
||||
swig.cmo \
|
||||
-package dl -linkpkg \
|
||||
$(INTERFACE:%.i=%.cmo) $(PROGFILE:%.ml=%.cmo)
|
||||
test -z "$(PROGFILE)" || $(OCC) $(OCAMLPP) -c $(PROGFILE)
|
||||
$(NOLINK) || $(OCAMLFIND) $(OCC) -g -ccopt -g -cclib -g -custom -o $(TARGET) swig.cmo -package dl -linkpkg $(INTERFACE:%.i=%.cmo) $(PROGFILE:%.ml=%.cmo)
|
||||
|
||||
ocaml_static_toplevel: $(SRCDIR_SRCS)
|
||||
$(OCAMLCORE)
|
||||
|
|
@ -952,72 +939,41 @@ ocaml_static_toplevel: $(SRCDIR_SRCS)
|
|||
$(OCC) -g -c -ccopt -g -ccopt "$(INCLUDES)" $(ISRCS) $(SRCDIR_SRCS)
|
||||
$(OCC) -g -c $(INTERFACE:%.i=%.mli)
|
||||
$(OCC) -g -c $(INTERFACE:%.i=%.ml)
|
||||
test -z "$(PROGFILE)" || test -f "$(PROGFILE)" && \
|
||||
$(OCC) $(OCAMLPP) -c $(PROGFILE)
|
||||
$(NOLINK) || $(OCAMLMKTOP) \
|
||||
swig.cmo \
|
||||
-I $(OCAMLP4WHERE) camlp4o.cma swigp4.cmo \
|
||||
-g -ccopt -g -cclib -g -custom -o $(TARGET)_top \
|
||||
$(INTERFACE:%.i=%.cmo) \
|
||||
$(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) -cclib "$(LIBS)"
|
||||
test -z "$(PROGFILE)" || $(OCC) $(OCAMLPP) -c $(PROGFILE)
|
||||
$(NOLINK) || $(OCAMLMKTOP) swig.cmo -I $(OCAMLP4WHERE) camlp4o.cma swigp4.cmo -g -ccopt -g -cclib -g -custom -o $(TARGET)_top $(INTERFACE:%.i=%.cmo) $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) -cclib "$(LIBS)"
|
||||
|
||||
ocaml_static_cpp: $(SRCDIR_SRCS)
|
||||
$(OCAMLCORE)
|
||||
$(SWIG) -ocaml -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
|
||||
cp $(ICXXSRCS) $(ICXXSRCS:%.cxx=%.c)
|
||||
$(OCC) -cc '$(CXX) -Wno-write-strings' -g -c -ccopt -g -ccopt "-xc++ $(INCLUDES)" \
|
||||
$(ICXXSRCS:%.cxx=%.c) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS)
|
||||
$(OCC) -cc '$(CXX) -Wno-write-strings' -g -c -ccopt -g -ccopt "-xc++ $(INCLUDES)" $(ICXXSRCS:%.cxx=%.c) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS)
|
||||
$(OCC) -g -c $(INTERFACE:%.i=%.mli)
|
||||
$(OCC) -g -c $(INTERFACE:%.i=%.ml)
|
||||
test -z "$(PROGFILE)" || test -f "$(PROGFILE)" && \
|
||||
$(OCC) $(OCAMLPP) -c $(PROGFILE)
|
||||
$(NOLINK) || $(OCC) -g -ccopt -g -cclib -g -custom -o $(TARGET) \
|
||||
swig.cmo \
|
||||
$(INTERFACE:%.i=%.cmo) \
|
||||
$(PROGFILE:%.ml=%.cmo) \
|
||||
$(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) \
|
||||
-cclib "$(LIBS)" -cc '$(CXX) -Wno-write-strings'
|
||||
test -z "$(PROGFILE)" || $(OCC) $(OCAMLPP) -c $(PROGFILE)
|
||||
$(NOLINK) || $(OCC) -g -ccopt -g -cclib -g -custom -o $(TARGET) swig.cmo $(INTERFACE:%.i=%.cmo) $(PROGFILE:%.ml=%.cmo) $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) -cclib "$(LIBS)" -cc '$(CXX) -Wno-write-strings'
|
||||
|
||||
ocaml_static_cpp_toplevel: $(SRCDIR_SRCS)
|
||||
$(OCAMLCORE)
|
||||
$(SWIG) -ocaml -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
|
||||
cp $(ICXXSRCS) $(ICXXSRCS:%.cxx=%.c)
|
||||
$(OCC) -cc '$(CXX) -Wno-write-strings' -g -c -ccopt -g -ccopt "-xc++ $(INCLUDES)" \
|
||||
$(ICXXSRCS:%.cxx=%.c) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS)
|
||||
$(OCC) -cc '$(CXX) -Wno-write-strings' -g -c -ccopt -g -ccopt "-xc++ $(INCLUDES)" $(ICXXSRCS:%.cxx=%.c) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS)
|
||||
$(OCC) -g -c $(INTERFACE:%.i=%.mli)
|
||||
$(OCC) -g -c $(INTERFACE:%.i=%.ml)
|
||||
test -z "$(PROGFILE)" || test -f "$(PROGFILE)" && \
|
||||
$(OCC) $(OCAMLPP) -c $(PROGFILE)
|
||||
$(NOLINK) || $(OCAMLMKTOP) \
|
||||
swig.cmo \
|
||||
-I $(OCAMLP4WHERE) dynlink.cma camlp4o.cma swigp4.cmo \
|
||||
-g -ccopt -g -cclib -g -custom -o $(TARGET)_top \
|
||||
$(INTERFACE:%.i=%.cmo) \
|
||||
$(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) \
|
||||
-cclib "$(LIBS)" -cc '$(CXX) -Wno-write-strings'
|
||||
test -z "$(PROGFILE)" || $(OCC) $(OCAMLPP) -c $(PROGFILE)
|
||||
$(NOLINK) || $(OCAMLMKTOP) swig.cmo -I $(OCAMLP4WHERE) dynlink.cma camlp4o.cma swigp4.cmo -g -ccopt -g -cclib -g -custom -o $(TARGET)_top $(INTERFACE:%.i=%.cmo) $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) -cclib "$(LIBS)" -cc '$(CXX) -Wno-write-strings'
|
||||
|
||||
ocaml_dynamic_cpp: $(SRCDIR_SRCS)
|
||||
$(OCAMLCORE)
|
||||
$(SWIG) -ocaml -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
|
||||
cp $(ICXXSRCS) $(ICXXSRCS:%.cxx=%.c)
|
||||
$(OCC) -cc '$(CXX) -Wno-write-strings' -g -c -ccopt -g -ccopt "-xc++ $(INCLUDES)" \
|
||||
$(ICXXSRCS:%.cxx=%.c) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) -ccopt -fPIC
|
||||
$(CXXSHARED) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $(INTERFACE:%.i=%@SO@) \
|
||||
$(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) \
|
||||
$(CPP_DLLIBS) $(LIBS)
|
||||
$(OCAMLDLGEN) $(INTERFACE:%.i=%.ml) $(INTERFACE:%.i=%@SO@) > \
|
||||
$(INTERFACE:%.i=%_dynamic.ml)
|
||||
$(OCC) -cc '$(CXX) -Wno-write-strings' -g -c -ccopt -g -ccopt "-xc++ $(INCLUDES)" $(ICXXSRCS:%.cxx=%.c) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) -ccopt -fPIC
|
||||
$(CXXSHARED) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $(INTERFACE:%.i=%@SO@) $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) $(CPP_DLLIBS) $(LIBS)
|
||||
$(OCAMLDLGEN) $(INTERFACE:%.i=%.ml) $(INTERFACE:%.i=%@SO@) > $(INTERFACE:%.i=%_dynamic.ml)
|
||||
mv $(INTERFACE:%.i=%_dynamic.ml) $(INTERFACE:%.i=%.ml)
|
||||
rm $(INTERFACE:%.i=%.mli)
|
||||
$(OCAMLFIND) $(OCC) -g -c -package dl $(INTERFACE:%.i=%.ml)
|
||||
test -z "$(PROGFILE)" || test -f "$(PROGFILE)" && \
|
||||
$(OCC) $(OCAMLPP) -c $(PROGFILE)
|
||||
$(NOLINK) || $(OCAMLFIND) \
|
||||
swig.cmo \
|
||||
$(OCC) -cclib -export-dynamic -g -ccopt -g -cclib -g -custom \
|
||||
-o $(TARGET) \
|
||||
-package dl -linkpkg \
|
||||
$(INTERFACE:%.i=%.cmo) $(PROGFILE:%.ml=%.cmo) -cc '$(CXX) -Wno-write-strings'
|
||||
test -z "$(PROGFILE)" || $(OCC) $(OCAMLPP) -c $(PROGFILE)
|
||||
$(NOLINK) || $(OCAMLFIND) swig.cmo $(OCC) -cclib -export-dynamic -g -ccopt -g -cclib -g -custom -o $(TARGET) -package dl -linkpkg $(INTERFACE:%.i=%.cmo) $(PROGFILE:%.ml=%.cmo) -cc '$(CXX) -Wno-write-strings'
|
||||
|
||||
# -----------------------------------------------------------------
|
||||
# Run ocaml example
|
||||
|
|
@ -1116,7 +1072,57 @@ ruby_clean:
|
|||
rm -f *.@OBJEXT@ *$(RUBY_SO)
|
||||
|
||||
##################################################################
|
||||
##### PHP ######
|
||||
##### PHP5 ######
|
||||
##################################################################
|
||||
|
||||
PHP5 = @PHP5@
|
||||
PHP5_INCLUDE = @PHP5INC@
|
||||
PHP5_SO = @PHP5_SO@
|
||||
PHP5_SCRIPT = $(SRCDIR)$(RUNME).php
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
# Build a PHP5 dynamically loadable module (C)
|
||||
# -------------------------------------------------------------------
|
||||
|
||||
php5: $(SRCDIR_SRCS)
|
||||
$(SWIG) -php5 $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
|
||||
$(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(SRCDIR_SRCS) $(ISRCS) $(INCLUDES) $(PHP5_INCLUDE)
|
||||
$(LDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(PHP5_SO)
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Build a PHP5 dynamically loadable module (C++)
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
php5_cpp: $(SRCDIR_SRCS)
|
||||
$(SWIG) -php5 -cppext cxx -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
|
||||
$(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(ICXXSRCS) $(INCLUDES) $(PHP5_INCLUDE)
|
||||
$(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(PHP5_SO)
|
||||
|
||||
# -----------------------------------------------------------------
|
||||
# Running a PHP5 example
|
||||
# -----------------------------------------------------------------
|
||||
|
||||
php5_run:
|
||||
$(RUNTOOL) $(PHP5) -n -q -d extension_dir=. -d safe_mode=Off $(PHP5_SCRIPT) $(RUNPIPE)
|
||||
|
||||
# -----------------------------------------------------------------
|
||||
# Version display
|
||||
# -----------------------------------------------------------------
|
||||
|
||||
php5_version:
|
||||
$(PHP5) -v | head -n 1
|
||||
|
||||
# -----------------------------------------------------------------
|
||||
# Cleaning the PHP5 examples
|
||||
# -----------------------------------------------------------------
|
||||
|
||||
php5_clean:
|
||||
rm -f *_wrap* *~ .~* example.php php_example.h
|
||||
rm -f core @EXTRA_CLEAN@
|
||||
rm -f *.@OBJEXT@ *$(PHP5_SO)
|
||||
|
||||
##################################################################
|
||||
##### PHP7 ######
|
||||
##################################################################
|
||||
|
||||
PHP = @PHP@
|
||||
|
|
@ -1129,7 +1135,7 @@ PHP_SCRIPT = $(SRCDIR)$(RUNME).php
|
|||
# -------------------------------------------------------------------
|
||||
|
||||
php: $(SRCDIR_SRCS)
|
||||
$(SWIG) -php $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
|
||||
$(SWIG) -php7 $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
|
||||
$(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(SRCDIR_SRCS) $(ISRCS) $(INCLUDES) $(PHP_INCLUDE)
|
||||
$(LDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(PHP_SO)
|
||||
|
||||
|
|
@ -1138,7 +1144,7 @@ php: $(SRCDIR_SRCS)
|
|||
# --------------------------------------------------------------------
|
||||
|
||||
php_cpp: $(SRCDIR_SRCS)
|
||||
$(SWIG) -php -cppext cxx -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
|
||||
$(SWIG) -php7 -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
|
||||
$(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(ICXXSRCS) $(INCLUDES) $(PHP_INCLUDE)
|
||||
$(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(PHP_SO)
|
||||
|
||||
|
|
@ -1147,7 +1153,7 @@ php_cpp: $(SRCDIR_SRCS)
|
|||
# -----------------------------------------------------------------
|
||||
|
||||
php_run:
|
||||
$(RUNTOOL) $(PHP) -n -q -d extension_dir=. -d safe_mode=Off $(PHP_SCRIPT) $(RUNPIPE)
|
||||
$(RUNTOOL) $(PHP) -n -q -d extension_dir=. -d safe_mode=Off -d display_errors=stderr $(PHP_SCRIPT) $(RUNPIPE)
|
||||
|
||||
# -----------------------------------------------------------------
|
||||
# Version display
|
||||
|
|
|
|||
|
|
@ -1,6 +1,3 @@
|
|||
#!./matrix \
|
||||
-e do-test -s
|
||||
!#
|
||||
;;; Authors: David Beazley <beazley@cs.uchicago.edu>, 1999
|
||||
;;; Martin Froehlich <MartinFroehlich@ACM.org>, 2000
|
||||
;;;
|
||||
|
|
|
|||
|
|
@ -19,6 +19,10 @@ public:
|
|||
#if defined(_MSC_VER)
|
||||
#pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
|
||||
#endif
|
||||
#if __GNUC__ >= 7
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated" // dynamic exception specifications are deprecated in C++11
|
||||
#endif
|
||||
|
||||
class Test {
|
||||
public:
|
||||
|
|
@ -50,4 +54,7 @@ public:
|
|||
#if defined(_MSC_VER)
|
||||
#pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
|
||||
#endif
|
||||
#if __GNUC__ >= 7
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -19,10 +19,14 @@ public:
|
|||
#if defined(_MSC_VER)
|
||||
#pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
|
||||
#endif
|
||||
#if __GNUC__ >= 7
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated" // dynamic exception specifications are deprecated in C++11
|
||||
#endif
|
||||
|
||||
class Test {
|
||||
public:
|
||||
int simple() throw(int&) {
|
||||
int simple() throw(int) {
|
||||
throw(37);
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -50,4 +54,7 @@ public:
|
|||
#if defined(_MSC_VER)
|
||||
#pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
|
||||
#endif
|
||||
#if __GNUC__ >= 7
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -1,18 +1,18 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>SWIG:Examples:python:simple</title>
|
||||
<title>SWIG:Examples:ocaml:simple</title>
|
||||
</head>
|
||||
|
||||
<body bgcolor="#ffffff">
|
||||
|
||||
|
||||
<tt>SWIG/Examples/python/simple/</tt>
|
||||
<tt>SWIG/Examples/ocaml/simple/</tt>
|
||||
<hr>
|
||||
|
||||
<H2>Simple Python Example</H2>
|
||||
<H2>Simple Ocaml Example</H2>
|
||||
|
||||
<p>
|
||||
This example illustrates how you can hook Python to a very simple C program containing
|
||||
This example illustrates how you can hook Ocaml to a very simple C program containing
|
||||
a function and a global variable.
|
||||
|
||||
<h2>The C Code</h2>
|
||||
|
|
@ -57,7 +57,7 @@ extern double Foo;
|
|||
<h2>Compilation</h2>
|
||||
|
||||
<ol>
|
||||
<li><tt>swig -python <a href="example.i">example.i</a></tt>
|
||||
<li><tt>swig -ocaml <a href="example.i">example.i</a></tt>
|
||||
<p>
|
||||
<li>Compile <tt><a href="example_wrap.c">example_wrap.c</a></tt> and <tt><a href="example.c">example.c</a></tt>
|
||||
to create the extension <tt>examplemodule.so</tt>.
|
||||
|
|
@ -65,29 +65,29 @@ to create the extension <tt>examplemodule.so</tt>.
|
|||
|
||||
<h2>Using the extension</h2>
|
||||
|
||||
Click <a href="example.py">here</a> to see a script that calls our C functions from Python.
|
||||
Click <a href="example.ml">here</a> to see a script that calls our C functions from Ocaml.
|
||||
|
||||
<h2>Key points</h2>
|
||||
|
||||
<ul>
|
||||
<li>Use the <tt>import</tt> statement to load your extension module from Python. For example:
|
||||
<li>Use the <tt>open</tt> statement to load your extension module from Ocaml. For example:
|
||||
<blockquote>
|
||||
<pre>
|
||||
import example
|
||||
open Example
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<li>C functions work just like Python functions. For example:
|
||||
<li>C functions work just like Ocaml functions. For example:
|
||||
<blockquote>
|
||||
<pre>
|
||||
g = example.gcd(42,105)
|
||||
let g = _gcd '(x,y) as int
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<li>C global variables are accessed through a special variable called 'cvar'. For example:
|
||||
<li>C global variable Foo is wrapped as _Foo in ocaml. For example:
|
||||
<blockquote>
|
||||
<pre>
|
||||
a = example.cvar.Foo
|
||||
let _ = Printf.printf "Foo = %f\n" (_Foo '() as float)
|
||||
</pre>
|
||||
</blockquote>
|
||||
</ul>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
# file: runme.m
|
||||
# do not dump Octave core
|
||||
if exist("crash_dumps_octave_core", "builtin")
|
||||
crash_dumps_octave_core(0);
|
||||
endif
|
||||
|
||||
# This file illustrates the cross language polymorphism using directors.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
# file: runme.m
|
||||
# do not dump Octave core
|
||||
if exist("crash_dumps_octave_core", "builtin")
|
||||
crash_dumps_octave_core(0);
|
||||
endif
|
||||
|
||||
# This file illustrates the proxy class C++ interface generated
|
||||
# by SWIG.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
# file: runme.m
|
||||
# do not dump Octave core
|
||||
if exist("crash_dumps_octave_core", "builtin")
|
||||
crash_dumps_octave_core(0);
|
||||
endif
|
||||
|
||||
swigexample
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
# file: runme.m
|
||||
# do not dump Octave core
|
||||
if exist("crash_dumps_octave_core", "builtin")
|
||||
crash_dumps_octave_core(0);
|
||||
endif
|
||||
|
||||
swigexample
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
# file: runme.m
|
||||
# do not dump Octave core
|
||||
if exist("crash_dumps_octave_core", "builtin")
|
||||
crash_dumps_octave_core(0);
|
||||
endif
|
||||
|
||||
swigexample
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
# file: runme.m
|
||||
# do not dump Octave core
|
||||
if exist("crash_dumps_octave_core", "builtin")
|
||||
crash_dumps_octave_core(0);
|
||||
endif
|
||||
|
||||
# This file illustrates the cross language polymorphism using directors.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
# file: runme.m
|
||||
# do not dump Octave core
|
||||
if exist("crash_dumps_octave_core", "builtin")
|
||||
crash_dumps_octave_core(0);
|
||||
endif
|
||||
|
||||
swigexample
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
# file: runme.m
|
||||
# do not dump Octave core
|
||||
if exist("crash_dumps_octave_core", "builtin")
|
||||
crash_dumps_octave_core(0);
|
||||
endif
|
||||
|
||||
swigexample
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,8 @@
|
|||
# do not dump Octave core
|
||||
if exist("crash_dumps_octave_core", "builtin")
|
||||
crash_dumps_octave_core(0);
|
||||
endif
|
||||
|
||||
# Operator overloading example
|
||||
swigexample
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
# file: runme_args.m
|
||||
# do not dump Octave core
|
||||
if exist("crash_dumps_octave_core", "builtin")
|
||||
crash_dumps_octave_core(0);
|
||||
endif
|
||||
|
||||
# load module
|
||||
clear all;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,8 @@
|
|||
# do not dump Octave core
|
||||
if exist("crash_dumps_octave_core", "builtin")
|
||||
crash_dumps_octave_core(0);
|
||||
endif
|
||||
|
||||
# Operator overloading example
|
||||
swigexample
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
# file: runme.m
|
||||
# do not dump Octave core
|
||||
if exist("crash_dumps_octave_core", "builtin")
|
||||
crash_dumps_octave_core(0);
|
||||
endif
|
||||
|
||||
swigexample;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
# file: runme.m
|
||||
# do not dump Octave core
|
||||
if exist("crash_dumps_octave_core", "builtin")
|
||||
crash_dumps_octave_core(0);
|
||||
endif
|
||||
|
||||
# This file illustrates the manipulation of C++ references in Octave
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
# file: runme.m
|
||||
# do not dump Octave core
|
||||
if exist("crash_dumps_octave_core", "builtin")
|
||||
crash_dumps_octave_core(0);
|
||||
endif
|
||||
|
||||
swigexample
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
# file: runme.m
|
||||
# do not dump Octave core
|
||||
if exist("crash_dumps_octave_core", "builtin")
|
||||
crash_dumps_octave_core(0);
|
||||
endif
|
||||
|
||||
swigexample
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
# file: runme.m
|
||||
# do not dump Octave core
|
||||
if exist("crash_dumps_octave_core", "builtin")
|
||||
crash_dumps_octave_core(0);
|
||||
endif
|
||||
|
||||
swigexample
|
||||
|
||||
|
|
|
|||
|
|
@ -15,10 +15,5 @@ build:
|
|||
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
|
||||
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' php_cpp
|
||||
|
||||
static:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' $(SWIGLIB) CXXSRCS='$(CXXSRCS)' \
|
||||
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
|
||||
SWIGOPT='$(SWIGOPT)' TARGET='myphp' INTERFACE='$(INTERFACE)' php_cpp_static
|
||||
|
||||
clean:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean
|
||||
|
|
|
|||
|
|
@ -16,11 +16,5 @@ build:
|
|||
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
|
||||
php_cpp
|
||||
|
||||
static:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
|
||||
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
|
||||
SWIGOPT='$(SWIGOPT)' TARGET='myphp' INTERFACE='$(INTERFACE)' \
|
||||
php_cpp_static
|
||||
|
||||
clean:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean
|
||||
|
|
|
|||
|
|
@ -16,11 +16,5 @@ build:
|
|||
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
|
||||
php
|
||||
|
||||
static:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
|
||||
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
|
||||
SWIGOPT='$(SWIGOPT)' TARGET='myphp' INTERFACE='$(INTERFACE)' \
|
||||
php_static
|
||||
|
||||
clean:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean
|
||||
|
|
|
|||
|
|
@ -16,11 +16,5 @@ build:
|
|||
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
|
||||
php
|
||||
|
||||
static:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
|
||||
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
|
||||
SWIGOPT='$(SWIGOPT)' TARGET='myphp' INTERFACE='$(INTERFACE)' \
|
||||
php_static
|
||||
|
||||
clean:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean
|
||||
|
|
|
|||
|
|
@ -16,11 +16,5 @@ build:
|
|||
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
|
||||
php_cpp
|
||||
|
||||
static:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
|
||||
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
|
||||
SWIGOPT='$(SWIGOPT)' TARGET='myphp' INTERFACE='$(INTERFACE)' \
|
||||
php_cpp_static
|
||||
|
||||
clean:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean
|
||||
|
|
|
|||
|
|
@ -16,11 +16,5 @@ build:
|
|||
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
|
||||
php_cpp
|
||||
|
||||
static:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
|
||||
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
|
||||
SWIGOPT='$(SWIGOPT)' TARGET='myphp' INTERFACE='$(INTERFACE)' \
|
||||
php_cpp_static
|
||||
|
||||
clean:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean
|
||||
|
|
|
|||
|
|
@ -15,10 +15,5 @@ build:
|
|||
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
|
||||
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' php_cpp
|
||||
|
||||
static:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' $(SWIGLIB) CXXSRCS='$(CXXSRCS)' \
|
||||
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
|
||||
SWIGOPT='$(SWIGOPT)' TARGET='myphp' INTERFACE='$(INTERFACE)' php_cpp_static
|
||||
|
||||
clean:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean
|
||||
|
|
|
|||
|
|
@ -16,11 +16,5 @@ build:
|
|||
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
|
||||
php
|
||||
|
||||
static:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
|
||||
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
|
||||
SWIGOPT='$(SWIGOPT)' TARGET='myphp' INTERFACE='$(INTERFACE)' \
|
||||
php_static
|
||||
|
||||
clean:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean
|
||||
|
|
|
|||
|
|
@ -16,11 +16,5 @@ build:
|
|||
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
|
||||
php_cpp
|
||||
|
||||
static:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
|
||||
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
|
||||
SWIGOPT='$(SWIGOPT)' TARGET='myphp' INTERFACE='$(INTERFACE)' \
|
||||
php_cpp_static
|
||||
|
||||
clean:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean
|
||||
|
|
|
|||
|
|
@ -16,11 +16,5 @@ build:
|
|||
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
|
||||
php
|
||||
|
||||
static:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
|
||||
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
|
||||
SWIGOPT='$(SWIGOPT)' TARGET='myphp' INTERFACE='$(INTERFACE)' \
|
||||
php_static
|
||||
|
||||
clean:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean
|
||||
|
|
|
|||
|
|
@ -16,11 +16,5 @@ build:
|
|||
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
|
||||
php
|
||||
|
||||
static:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
|
||||
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
|
||||
SWIGOPT='$(SWIGOPT)' TARGET='myphp' INTERFACE='$(INTERFACE)' \
|
||||
php_static
|
||||
|
||||
clean:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
?>
|
||||
|
|
|
|||
|
|
@ -16,11 +16,5 @@ build:
|
|||
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
|
||||
php_cpp
|
||||
|
||||
static:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
|
||||
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
|
||||
SWIGOPT='$(SWIGOPT)' TARGET='myphp' INTERFACE='$(INTERFACE)' \
|
||||
php_cpp_static
|
||||
|
||||
clean:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean
|
||||
|
|
|
|||
|
|
@ -16,11 +16,5 @@ build:
|
|||
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
|
||||
php_cpp
|
||||
|
||||
static:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
|
||||
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
|
||||
SWIGOPT='$(SWIGOPT)' TARGET='myphp' INTERFACE='$(INTERFACE)' \
|
||||
php_cpp_static
|
||||
|
||||
clean:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean
|
||||
|
|
|
|||
|
|
@ -16,11 +16,5 @@ build:
|
|||
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
|
||||
php
|
||||
|
||||
static:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
|
||||
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
|
||||
SWIGOPT='$(SWIGOPT)' TARGET='myphp' INTERFACE='$(INTERFACE)' \
|
||||
php_static
|
||||
|
||||
clean:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean
|
||||
|
|
|
|||
|
|
@ -16,11 +16,5 @@ build:
|
|||
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
|
||||
php_cpp
|
||||
|
||||
static:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
|
||||
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
|
||||
SWIGOPT='$(SWIGOPT)' TARGET='myphp' INTERFACE='$(INTERFACE)' \
|
||||
php_cpp_static
|
||||
|
||||
clean:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean
|
||||
|
|
|
|||
|
|
@ -16,11 +16,5 @@ build:
|
|||
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
|
||||
php
|
||||
|
||||
static:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
|
||||
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
|
||||
SWIGOPT='$(SWIGOPT)' TARGET='myphp' INTERFACE='$(INTERFACE)' \
|
||||
php_static
|
||||
|
||||
clean:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean
|
||||
|
|
|
|||
|
|
@ -16,11 +16,5 @@ build:
|
|||
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
|
||||
php
|
||||
|
||||
static:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
|
||||
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
|
||||
SWIGOPT='$(SWIGOPT)' TARGET='myphp' INTERFACE='$(INTERFACE)' \
|
||||
php_static
|
||||
|
||||
clean:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean
|
||||
|
|
|
|||
19
Examples/php5/callback/Makefile
Normal file
19
Examples/php5/callback/Makefile
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
TOP = ../..
|
||||
SWIGEXE = $(TOP)/../swig
|
||||
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
|
||||
CXXSRCS = example.cxx
|
||||
TARGET = example
|
||||
INTERFACE = example.i
|
||||
LIBS = -lm
|
||||
SWIGOPT =
|
||||
|
||||
check: build
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php5_run
|
||||
|
||||
build:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' $(SWIGLIB) CXXSRCS='$(CXXSRCS)' \
|
||||
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
|
||||
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' php5_cpp
|
||||
|
||||
clean:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php5_clean
|
||||
4
Examples/php5/callback/example.cxx
Normal file
4
Examples/php5/callback/example.cxx
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
/* File : example.cxx */
|
||||
|
||||
#include "example.h"
|
||||
|
||||
22
Examples/php5/callback/example.h
Normal file
22
Examples/php5/callback/example.h
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/* File : example.h */
|
||||
|
||||
#include <iostream>
|
||||
|
||||
class Callback {
|
||||
public:
|
||||
virtual ~Callback() { std::cout << "Callback::~Callback()" << std:: endl; }
|
||||
virtual void run() { std::cout << "Callback::run()" << std::endl; }
|
||||
};
|
||||
|
||||
|
||||
class Caller {
|
||||
private:
|
||||
Callback *_callback;
|
||||
public:
|
||||
Caller(): _callback(0) {}
|
||||
~Caller() { delCallback(); }
|
||||
void delCallback() { delete _callback; _callback = 0; }
|
||||
void setCallback(Callback *cb) { delCallback(); _callback = cb; }
|
||||
void call() { if (_callback) _callback->run(); }
|
||||
};
|
||||
|
||||
11
Examples/php5/callback/example.i
Normal file
11
Examples/php5/callback/example.i
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
/* File : example.i */
|
||||
%module(directors="1") example
|
||||
%{
|
||||
#include "example.h"
|
||||
%}
|
||||
|
||||
/* turn on director wrapping Callback */
|
||||
%feature("director") Callback;
|
||||
|
||||
%include "example.h"
|
||||
|
||||
19
Examples/php5/callback/index.html
Normal file
19
Examples/php5/callback/index.html
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>SWIG:Examples:php5:callback</title>
|
||||
</head>
|
||||
|
||||
<body bgcolor="#ffffff">
|
||||
|
||||
|
||||
<tt>SWIG/Examples/php5/callback/</tt>
|
||||
<hr>
|
||||
|
||||
<H2>Implementing C++ callbacks in PHP5</H2>
|
||||
|
||||
<p>
|
||||
This example illustrates how to use directors to implement C++ callbacks in PHP5.
|
||||
|
||||
<hr>
|
||||
</body>
|
||||
</html>
|
||||
47
Examples/php5/callback/runme.php
Normal file
47
Examples/php5/callback/runme.php
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
# This file illustrates the cross language polymorphism using directors.
|
||||
|
||||
require("example.php");
|
||||
|
||||
# Class, which overwrites Callback::run().
|
||||
|
||||
class PhpCallback extends Callback {
|
||||
function run() {
|
||||
print "PhpCallback.run()\n";
|
||||
}
|
||||
};
|
||||
|
||||
# Create an Caller instance
|
||||
|
||||
$caller = new Caller();
|
||||
|
||||
# Add a simple C++ callback (caller owns the callback, so
|
||||
# we disown it first by clearing the .thisown flag).
|
||||
|
||||
print "Adding and calling a normal C++ callback\n";
|
||||
print "----------------------------------------\n";
|
||||
|
||||
$callback = new Callback();
|
||||
$callback->thisown = 0;
|
||||
$caller->setCallback($callback);
|
||||
$caller->call();
|
||||
$caller->delCallback();
|
||||
|
||||
print "\n";
|
||||
print "Adding and calling a PHP callback\n";
|
||||
print "------------------------------------\n";
|
||||
|
||||
# Add a PHP callback.
|
||||
|
||||
$callback = new PhpCallback();
|
||||
$callback->thisown = 0;
|
||||
$caller->setCallback($callback);
|
||||
$caller->call();
|
||||
$caller->delCallback();
|
||||
|
||||
# All done.
|
||||
|
||||
print "php exit\n";
|
||||
|
||||
?>
|
||||
19
Examples/php5/check.list
Normal file
19
Examples/php5/check.list
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
# see top-level Makefile.in
|
||||
# (see also top-level configure.ac kludge)
|
||||
callback
|
||||
class
|
||||
constants
|
||||
cpointer
|
||||
disown
|
||||
enum
|
||||
extend
|
||||
funcptr
|
||||
overloading
|
||||
pointer
|
||||
pragmas
|
||||
proxy
|
||||
reference
|
||||
simple
|
||||
sync
|
||||
value
|
||||
variables
|
||||
20
Examples/php5/class/Makefile
Normal file
20
Examples/php5/class/Makefile
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
TOP = ../..
|
||||
SWIGEXE = $(TOP)/../swig
|
||||
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
|
||||
CXXSRCS = example.cxx
|
||||
TARGET = example
|
||||
INTERFACE = example.i
|
||||
LIBS =
|
||||
SWIGOPT =
|
||||
|
||||
check: build
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php5_run
|
||||
|
||||
build:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
|
||||
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
|
||||
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
|
||||
php5_cpp
|
||||
|
||||
clean:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php5_clean
|
||||
28
Examples/php5/class/example.cxx
Normal file
28
Examples/php5/class/example.cxx
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/* File : example.cxx */
|
||||
|
||||
#include "example.h"
|
||||
#define M_PI 3.14159265358979323846
|
||||
|
||||
/* Move the shape to a new location */
|
||||
void Shape::move(double dx, double dy) {
|
||||
x += dx;
|
||||
y += dy;
|
||||
}
|
||||
|
||||
int Shape::nshapes = 0;
|
||||
|
||||
double Circle::area() {
|
||||
return M_PI*radius*radius;
|
||||
}
|
||||
|
||||
double Circle::perimeter() {
|
||||
return 2*M_PI*radius;
|
||||
}
|
||||
|
||||
double Square::area() {
|
||||
return width*width;
|
||||
}
|
||||
|
||||
double Square::perimeter() {
|
||||
return 4*width;
|
||||
}
|
||||
34
Examples/php5/class/example.h
Normal file
34
Examples/php5/class/example.h
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/* File : example.h */
|
||||
|
||||
class Shape {
|
||||
public:
|
||||
Shape() {
|
||||
nshapes++;
|
||||
}
|
||||
virtual ~Shape() {
|
||||
nshapes--;
|
||||
}
|
||||
double x, y;
|
||||
void move(double dx, double dy);
|
||||
virtual double area() = 0;
|
||||
virtual double perimeter() = 0;
|
||||
static int nshapes;
|
||||
};
|
||||
|
||||
class Circle : public Shape {
|
||||
private:
|
||||
double radius;
|
||||
public:
|
||||
Circle(double r) : radius(r) { }
|
||||
virtual double area();
|
||||
virtual double perimeter();
|
||||
};
|
||||
|
||||
class Square : public Shape {
|
||||
private:
|
||||
double width;
|
||||
public:
|
||||
Square(double w) : width(w) { }
|
||||
virtual double area();
|
||||
virtual double perimeter();
|
||||
};
|
||||
9
Examples/php5/class/example.i
Normal file
9
Examples/php5/class/example.i
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
/* File : example.i */
|
||||
%module example
|
||||
|
||||
%{
|
||||
#include "example.h"
|
||||
%}
|
||||
|
||||
/* Let's just grab the original header file here */
|
||||
%include "example.h"
|
||||
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