Consistent formatting of example code in the docs
This commit is contained in:
parent
129ef8ea8f
commit
268b942865
25 changed files with 1705 additions and 1714 deletions
|
|
@ -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 ())
|
||||
|
||||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
|
@ -688,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>
|
||||
|
||||
|
|
@ -818,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>
|
||||
|
|
@ -858,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>
|
||||
|
||||
|
|
|
|||
|
|
@ -1021,18 +1021,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 +1155,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 +1220,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>
|
||||
|
|
@ -1643,20 +1641,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,
|
||||
|
|
@ -1940,10 +1938,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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
|
@ -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>
|
||||
|
|
@ -771,12 +771,12 @@ 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;
|
||||
|
|
@ -811,10 +811,10 @@ are defined. For example:
|
|||
<pre>
|
||||
/* Define a global exception handler */
|
||||
%feature("except") {
|
||||
try {
|
||||
$action
|
||||
}
|
||||
...
|
||||
try {
|
||||
$action
|
||||
}
|
||||
...
|
||||
}
|
||||
|
||||
... bunch of declarations ...
|
||||
|
|
@ -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>
|
||||
|
|
@ -993,21 +993,21 @@ 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 ...
|
||||
|
|
@ -1165,14 +1165,14 @@ in the Python module. You might use <tt>%feature</tt> to rewrite proxy/shadow cl
|
|||
%feature("shadow") Foo::bar(int) %{
|
||||
def bar(*args):
|
||||
if len(args) == 3:
|
||||
return apply(examplec.Foo_bar_id,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>
|
||||
|
|
|
|||
|
|
@ -229,8 +229,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);
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -1517,7 +1517,7 @@ common to see small code fragments of code generated using code like this:
|
|||
String *s = NewString("");
|
||||
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>
|
||||
|
|
@ -1703,8 +1703,8 @@ 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 */
|
||||
...
|
||||
/* n is virtual */
|
||||
...
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -1503,8 +1503,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 +1554,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 +1585,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
|
||||
|
|
@ -1645,7 +1645,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;
|
||||
|
|
@ -2011,11 +2011,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>
|
||||
|
|
|
|||
|
|
@ -134,17 +134,16 @@ 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);
|
||||
|
|
@ -436,44 +435,41 @@ Various features which were available for C headers can also be used
|
|||
<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>
|
||||
|
|
@ -778,10 +774,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
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -1090,13 +1090,14 @@ 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>
|
||||
|
|
@ -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,12 +1155,12 @@ 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();
|
||||
};
|
||||
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
|
@ -36,12 +36,12 @@ Example interface file:
|
|||
/* define a macro for the struct creation */
|
||||
%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;
|
||||
$1 = &temp;
|
||||
}
|
||||
%enddef
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
|
@ -314,7 +314,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
|
||||
|
|
@ -663,10 +663,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> >
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -1614,7 +1614,7 @@ class DoubleArray {
|
|||
}
|
||||
// Destroy an array
|
||||
~DoubleArray() {
|
||||
delete ptr;
|
||||
delete ptr;
|
||||
}
|
||||
// Return the length of the array
|
||||
int length() {
|
||||
|
|
@ -2173,11 +2173,11 @@ reference to be used as a char ** datatype.
|
|||
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);
|
||||
free(svs);
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
||||
|
|
@ -2492,7 +2492,7 @@ 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_ConvertPtr($input,(void **) &$1, $1_descriptor,0)) == -1) return NULL;
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2505,7 +2505,7 @@ For example:
|
|||
<div class="code">
|
||||
<pre>
|
||||
%typemap(in) Foo * {
|
||||
if ((SWIG_ConvertPtr($input,(void **) &$1, $descriptor(Foo *), 0)) == -1) return NULL;
|
||||
if ((SWIG_ConvertPtr($input,(void **) &$1, $descriptor(Foo *), 0)) == -1) return NULL;
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2997,9 +2997,9 @@ low-level helper functions. For example, this code now seems to work:
|
|||
<pre>
|
||||
my $a =
|
||||
[[1,0,0,0],
|
||||
[0,1,0,0],
|
||||
[0,0,1,0],
|
||||
[0,0,0,1]];
|
||||
[0,1,0,0],
|
||||
[0,0,1,0],
|
||||
[0,0,0,1]];
|
||||
set_transform($im, $a);
|
||||
</pre>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -995,7 +995,7 @@ require("mymodule.php");
|
|||
|
||||
class MyFoo extends Foo {
|
||||
function one() {
|
||||
print "one from php\n";
|
||||
print "one from php\n";
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
|
|
|
|||
|
|
@ -225,16 +225,16 @@ For example:
|
|||
%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
|
||||
|
|
@ -334,7 +334,7 @@ if you write code like this,
|
|||
%{
|
||||
#ifdef NEED_BLAH
|
||||
int blah() {
|
||||
...
|
||||
...
|
||||
}
|
||||
#endif
|
||||
%}
|
||||
|
|
@ -358,11 +358,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 +375,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>
|
||||
|
|
|
|||
|
|
@ -1262,12 +1262,12 @@ consider writing some helper functions instead. For 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) {
|
||||
|
|
@ -1355,12 +1355,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>
|
||||
|
|
@ -1427,11 +1427,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>
|
||||
|
|
@ -1525,9 +1525,8 @@ 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>
|
||||
|
|
@ -1904,10 +1903,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>
|
||||
|
|
@ -1976,13 +1975,13 @@ 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&);
|
||||
~pair();
|
||||
typedef T1 first_type;
|
||||
typedef T2 second_type;
|
||||
T1 first;
|
||||
T2 second;
|
||||
pair();
|
||||
pair(const T1&, const T2&);
|
||||
~pair();
|
||||
};
|
||||
|
||||
%template(pairii) pair<int,int>;
|
||||
|
|
@ -2037,9 +2036,9 @@ that implements <tt>operator->()</tt> like this:
|
|||
<div class="code">
|
||||
<pre>
|
||||
template<class T> class SmartPtr {
|
||||
...
|
||||
T *operator->();
|
||||
...
|
||||
...
|
||||
T *operator->();
|
||||
...
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2052,8 +2051,8 @@ Then, if you have a class like this,
|
|||
<pre>
|
||||
class Foo {
|
||||
public:
|
||||
int x;
|
||||
int bar();
|
||||
int x;
|
||||
int bar();
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2154,9 +2153,9 @@ have a class like this
|
|||
<pre>
|
||||
class Foo {
|
||||
public:
|
||||
int x;
|
||||
int spam(int);
|
||||
...
|
||||
int x;
|
||||
int spam(int);
|
||||
...
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -2749,10 +2748,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>
|
||||
|
|
@ -3319,16 +3318,16 @@ functions. Just use the <tt>%inline</tt> directive. For example:
|
|||
%inline %{
|
||||
/* Note: double[4][4] is equivalent to a pointer to an array double (*)[4] */
|
||||
double (*new_mat44())[4] {
|
||||
return (double (*)[4]) malloc(16*sizeof(double));
|
||||
return (double (*)[4]) malloc(16*sizeof(double));
|
||||
}
|
||||
void free_mat44(double (*x)[4]) {
|
||||
free(x);
|
||||
free(x);
|
||||
}
|
||||
void mat44_set(double x[4][4], int i, int j, double v) {
|
||||
x[i][j] = v;
|
||||
x[i][j] = v;
|
||||
}
|
||||
double mat44_get(double x[4][4], int i, int j) {
|
||||
return x[i][j];
|
||||
return x[i][j];
|
||||
}
|
||||
%}
|
||||
</pre>
|
||||
|
|
@ -3374,12 +3373,12 @@ void set_transform(Image *im, double x[4][4]);
|
|||
/* Rewrite the high level interface to set_transform */
|
||||
%pythoncode %{
|
||||
def set_transform(im,x):
|
||||
a = new_mat44()
|
||||
for i in range(4):
|
||||
for j in range(4):
|
||||
mat44_set(a,i,j,x[i][j])
|
||||
_example.set_transform(im,a)
|
||||
free_mat44(a)
|
||||
a = new_mat44()
|
||||
for i in range(4):
|
||||
for j in range(4):
|
||||
mat44_set(a,i,j,x[i][j])
|
||||
_example.set_transform(im,a)
|
||||
free_mat44(a)
|
||||
%}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3529,11 +3528,11 @@ proxy, just before the return statement.
|
|||
// Add python code to bar()
|
||||
|
||||
%feature("pythonprepend") Foo::bar(int) %{
|
||||
#do something before C++ call
|
||||
#do something before C++ call
|
||||
%}
|
||||
|
||||
%feature("pythonappend") Foo::bar(int) %{
|
||||
#do something after C++ call
|
||||
#do something after C++ call
|
||||
%}
|
||||
|
||||
|
||||
|
|
@ -3558,11 +3557,11 @@ SWIG version 1.3.28 you can use the directive forms
|
|||
// Add python code to bar()
|
||||
|
||||
%pythonprepend Foo::bar(int) %{
|
||||
#do something before C++ call
|
||||
#do something before C++ call
|
||||
%}
|
||||
|
||||
%pythonappend Foo::bar(int) %{
|
||||
#do something after C++ call
|
||||
#do something after C++ call
|
||||
%}
|
||||
|
||||
|
||||
|
|
@ -3587,11 +3586,11 @@ as it will then get attached to all the overloaded C++ methods. For example:
|
|||
// Add python code to bar()
|
||||
|
||||
%pythonprepend Foo::bar %{
|
||||
#do something before C++ call
|
||||
#do something before C++ call
|
||||
%}
|
||||
|
||||
%pythonappend Foo::bar %{
|
||||
#do something after C++ call
|
||||
#do something after C++ call
|
||||
%}
|
||||
|
||||
|
||||
|
|
@ -3625,22 +3624,22 @@ Here is a simple example:
|
|||
%}
|
||||
|
||||
struct Vector {
|
||||
double x,y,z;
|
||||
double x,y,z;
|
||||
};
|
||||
|
||||
%extend Vector {
|
||||
char *__str__() {
|
||||
static char tmp[1024];
|
||||
sprintf(tmp,"Vector(%g,%g,%g)", $self->x,$self->y,$self->z);
|
||||
return tmp;
|
||||
}
|
||||
Vector(double x, double y, double z) {
|
||||
Vector *v = (Vector *) malloc(sizeof(Vector));
|
||||
v->x = x;
|
||||
v->y = y;
|
||||
v->z = z;
|
||||
return v;
|
||||
}
|
||||
char *__str__() {
|
||||
static char tmp[1024];
|
||||
sprintf(tmp,"Vector(%g,%g,%g)", $self->x,$self->y,$self->z);
|
||||
return tmp;
|
||||
}
|
||||
Vector(double x, double y, double z) {
|
||||
Vector *v = (Vector *) malloc(sizeof(Vector));
|
||||
v->x = x;
|
||||
v->y = y;
|
||||
v->z = z;
|
||||
return v;
|
||||
}
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3666,13 +3665,13 @@ For example, if you wanted to overload a Python operator, you might do this:
|
|||
<div class="code">
|
||||
<pre>
|
||||
%extend Vector {
|
||||
Vector __add__(Vector *other) {
|
||||
Vector v;
|
||||
v.x = $self->x + other->x;
|
||||
v.y = $self->y + other->y;
|
||||
v.z = $self->z + other->z;
|
||||
return v;
|
||||
}
|
||||
Vector __add__(Vector *other) {
|
||||
Vector v;
|
||||
v.x = $self->x + other->x;
|
||||
v.y = $self->y + other->y;
|
||||
v.z = $self->z + other->z;
|
||||
return v;
|
||||
}
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3716,8 +3715,8 @@ or a NULL pointer perhaps). Here is a simple example of how you might handle th
|
|||
%exception malloc {
|
||||
$action
|
||||
if (!result) {
|
||||
PyErr_SetString(PyExc_MemoryError,"Not enough memory");
|
||||
SWIG_fail;
|
||||
PyErr_SetString(PyExc_MemoryError,"Not enough memory");
|
||||
SWIG_fail;
|
||||
}
|
||||
}
|
||||
void *malloc(size_t nbytes);
|
||||
|
|
@ -3746,11 +3745,11 @@ that. For example:
|
|||
<div class="code">
|
||||
<pre>
|
||||
%exception {
|
||||
$action
|
||||
if (err_occurred()) {
|
||||
PyErr_SetString(PyExc_RuntimeError, err_message());
|
||||
SWIG_fail;
|
||||
}
|
||||
$action
|
||||
if (err_occurred()) {
|
||||
PyErr_SetString(PyExc_RuntimeError, err_message());
|
||||
SWIG_fail;
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3766,18 +3765,18 @@ C++ exceptions are also easy to handle. For example, you can write code like th
|
|||
<div class="code">
|
||||
<pre>
|
||||
%exception getitem {
|
||||
try {
|
||||
$action
|
||||
} catch (std::out_of_range &e) {
|
||||
PyErr_SetString(PyExc_IndexError, const_cast<char*>(e.what()));
|
||||
SWIG_fail;
|
||||
}
|
||||
try {
|
||||
$action
|
||||
} catch (std::out_of_range &e) {
|
||||
PyErr_SetString(PyExc_IndexError, const_cast<char*>(e.what()));
|
||||
SWIG_fail;
|
||||
}
|
||||
}
|
||||
|
||||
class Base {
|
||||
public:
|
||||
Foo *getitem(int index); // Exception handled added
|
||||
...
|
||||
Foo *getitem(int index); // Exception handled added
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3852,7 +3851,7 @@ example:
|
|||
<div class="code">
|
||||
<pre>
|
||||
void add(int x, int y, int *result) {
|
||||
*result = x + y;
|
||||
*result = x + y;
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3864,7 +3863,7 @@ or perhaps
|
|||
<div class="code">
|
||||
<pre>
|
||||
int sub(int *x, int *y) {
|
||||
return *x-*y;
|
||||
return *x-*y;
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3929,7 +3928,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>
|
||||
|
|
@ -4465,8 +4464,8 @@ Typemaps can also be defined for groups of consecutive arguments. For example:
|
|||
<div class="code">
|
||||
<pre>
|
||||
%typemap(in) (char *str, int len) {
|
||||
$1 = PyString_AsString($input);
|
||||
$2 = PyString_Size($input);
|
||||
$1 = PyString_AsString($input);
|
||||
$2 = PyString_Size($input);
|
||||
};
|
||||
|
||||
int count(char c, char *str, int len);
|
||||
|
|
@ -4781,12 +4780,12 @@ object to be used as a <tt>char **</tt> object.
|
|||
// Now a test function
|
||||
%inline %{
|
||||
int print_args(char **argv) {
|
||||
int i = 0;
|
||||
while (argv[i]) {
|
||||
printf("argv[%d] = %s\n", i,argv[i]);
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
int i = 0;
|
||||
while (argv[i]) {
|
||||
printf("argv[%d] = %s\n", i,argv[i]);
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
%}
|
||||
|
||||
|
|
@ -5003,7 +5002,7 @@ no meaningful input value), an additional typemap can be written. For example:
|
|||
|
||||
<div class="code"><pre>
|
||||
%typemap(in,numinputs=0) double *OutValue(double temp) {
|
||||
$1 = &temp;
|
||||
$1 = &temp;
|
||||
}
|
||||
|
||||
</pre></div>
|
||||
|
|
@ -5085,22 +5084,22 @@ arrays of different sizes. To do this, you might write a typemap as follows:
|
|||
%typemap(in) double[ANY](double temp[$1_dim0]) {
|
||||
int i;
|
||||
if (!PySequence_Check($input)) {
|
||||
PyErr_SetString(PyExc_TypeError,"Expecting a sequence");
|
||||
SWIG_fail;
|
||||
PyErr_SetString(PyExc_TypeError,"Expecting a sequence");
|
||||
SWIG_fail;
|
||||
}
|
||||
if (PyObject_Length($input) != $1_dim0) {
|
||||
PyErr_SetString(PyExc_ValueError,"Expecting a sequence with $1_dim0 elements");
|
||||
SWIG_fail;
|
||||
PyErr_SetString(PyExc_ValueError,"Expecting a sequence with $1_dim0 elements");
|
||||
SWIG_fail;
|
||||
}
|
||||
for (i =0; i < $1_dim0; i++) {
|
||||
PyObject *o = PySequence_GetItem($input,i);
|
||||
if (!PyFloat_Check(o)) {
|
||||
Py_XDECREF(o);
|
||||
PyErr_SetString(PyExc_ValueError,"Expecting a sequence of floats");
|
||||
SWIG_fail;
|
||||
}
|
||||
temp[i] = PyFloat_AsDouble(o);
|
||||
Py_DECREF(o);
|
||||
PyObject *o = PySequence_GetItem($input,i);
|
||||
if (!PyFloat_Check(o)) {
|
||||
Py_XDECREF(o);
|
||||
PyErr_SetString(PyExc_ValueError,"Expecting a sequence of floats");
|
||||
SWIG_fail;
|
||||
}
|
||||
temp[i] = PyFloat_AsDouble(o);
|
||||
Py_DECREF(o);
|
||||
}
|
||||
$1 = &temp[0];
|
||||
}
|
||||
|
|
@ -5131,32 +5130,32 @@ to use a helper function instead. This will greatly reduce the amount of wrappe
|
|||
static int convert_darray(PyObject *input, double *ptr, int size) {
|
||||
int i;
|
||||
if (!PySequence_Check(input)) {
|
||||
PyErr_SetString(PyExc_TypeError,"Expecting a sequence");
|
||||
return 0;
|
||||
PyErr_SetString(PyExc_TypeError,"Expecting a sequence");
|
||||
return 0;
|
||||
}
|
||||
if (PyObject_Length(input) != size) {
|
||||
PyErr_SetString(PyExc_ValueError,"Sequence size mismatch");
|
||||
return 0;
|
||||
PyErr_SetString(PyExc_ValueError,"Sequence size mismatch");
|
||||
return 0;
|
||||
}
|
||||
for (i =0; i < size; i++) {
|
||||
PyObject *o = PySequence_GetItem(input,i);
|
||||
if (!PyFloat_Check(o)) {
|
||||
Py_XDECREF(o);
|
||||
PyErr_SetString(PyExc_ValueError,"Expecting a sequence of floats");
|
||||
return 0;
|
||||
}
|
||||
ptr[i] = PyFloat_AsDouble(o);
|
||||
Py_DECREF(o);
|
||||
PyObject *o = PySequence_GetItem(input,i);
|
||||
if (!PyFloat_Check(o)) {
|
||||
Py_XDECREF(o);
|
||||
PyErr_SetString(PyExc_ValueError,"Expecting a sequence of floats");
|
||||
return 0;
|
||||
}
|
||||
ptr[i] = PyFloat_AsDouble(o);
|
||||
Py_DECREF(o);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
%}
|
||||
|
||||
%typemap(in) double [ANY](double temp[$1_dim0]) {
|
||||
if (!convert_darray($input,temp,$1_dim0)) {
|
||||
SWIG_fail;
|
||||
}
|
||||
$1 = &temp[0];
|
||||
if (!convert_darray($input,temp,$1_dim0)) {
|
||||
SWIG_fail;
|
||||
}
|
||||
$1 = &temp[0];
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -5450,7 +5449,7 @@ resulting in
|
|||
<div class="targetlang">
|
||||
<pre>
|
||||
def function_name(*args, **kwargs):
|
||||
"""
|
||||
"""
|
||||
function_name(x, y, foo=None, bar=None) -> bool
|
||||
|
||||
Parameters
|
||||
|
|
|
|||
|
|
@ -1357,16 +1357,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 +1381,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 +1538,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 +1558,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 +1587,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>
|
||||
|
|
@ -2521,12 +2521,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 +2540,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>
|
||||
|
|
@ -2588,7 +2588,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>
|
||||
|
|
@ -2843,10 +2843,10 @@ double Vector_magnitude(Vector *v) {
|
|||
typedef struct Vector {
|
||||
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>
|
||||
|
|
@ -3083,7 +3083,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 +3100,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>
|
||||
|
|
@ -3183,23 +3183,23 @@ the wrapper file is as shown:
|
|||
<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>
|
||||
|
|
|
|||
|
|
@ -256,11 +256,11 @@ C++ class like this:
|
|||
<div class="code">
|
||||
<pre>
|
||||
class Foo {
|
||||
public:
|
||||
Foo();
|
||||
~Foo();
|
||||
int bar(int x);
|
||||
int x;
|
||||
public:
|
||||
Foo();
|
||||
~Foo();
|
||||
int bar(int x);
|
||||
int x;
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -272,24 +272,24 @@ Using C++ as pseudocode, a proxy class looks something like this:
|
|||
<div class="code">
|
||||
<pre>
|
||||
class FooProxy {
|
||||
private:
|
||||
Foo *self;
|
||||
public:
|
||||
FooProxy() {
|
||||
self = new_Foo();
|
||||
}
|
||||
~FooProxy() {
|
||||
delete_Foo(self);
|
||||
}
|
||||
int bar(int x) {
|
||||
return Foo_bar(self,x);
|
||||
}
|
||||
int x_get() {
|
||||
return Foo_x_get(self);
|
||||
}
|
||||
void x_set(int x) {
|
||||
Foo_x_set(self,x);
|
||||
}
|
||||
private:
|
||||
Foo *self;
|
||||
public:
|
||||
FooProxy() {
|
||||
self = new_Foo();
|
||||
}
|
||||
~FooProxy() {
|
||||
delete_Foo(self);
|
||||
}
|
||||
int bar(int x) {
|
||||
return Foo_bar(self,x);
|
||||
}
|
||||
int x_get() {
|
||||
return Foo_x_get(self);
|
||||
}
|
||||
void x_set(int x) {
|
||||
Foo_x_set(self,x);
|
||||
}
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -303,19 +303,19 @@ For example, in Python, the proxy might look roughly like this:
|
|||
<pre>
|
||||
class Foo:
|
||||
def __init__(self):
|
||||
self.this = new_Foo()
|
||||
self.this = new_Foo()
|
||||
def __del__(self):
|
||||
delete_Foo(self.this)
|
||||
delete_Foo(self.this)
|
||||
def bar(self,x):
|
||||
return Foo_bar(self.this,x)
|
||||
return Foo_bar(self.this,x)
|
||||
def __getattr__(self,name):
|
||||
if name == 'x':
|
||||
return Foo_x_get(self.this)
|
||||
...
|
||||
if name == 'x':
|
||||
return Foo_x_get(self.this)
|
||||
...
|
||||
def __setattr__(self,name,value):
|
||||
if name == 'x':
|
||||
Foo_x_set(self.this,value)
|
||||
...
|
||||
if name == 'x':
|
||||
Foo_x_set(self.this,value)
|
||||
...
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -338,10 +338,10 @@ C++ code:
|
|||
<pre>
|
||||
class Foo {
|
||||
public:
|
||||
Foo();
|
||||
~Foo();
|
||||
int bar(int x);
|
||||
int x;
|
||||
Foo();
|
||||
~Foo();
|
||||
int bar(int x);
|
||||
int x;
|
||||
};
|
||||
|
||||
class Spam {
|
||||
|
|
@ -407,45 +407,45 @@ roughly like this:
|
|||
<div class="code">
|
||||
<pre>
|
||||
class FooProxy {
|
||||
public:
|
||||
Foo *self;
|
||||
int thisown;
|
||||
public:
|
||||
Foo *self;
|
||||
int thisown;
|
||||
|
||||
FooProxy() {
|
||||
self = new_Foo();
|
||||
thisown = 1; // Newly created object
|
||||
}
|
||||
~FooProxy() {
|
||||
if (thisown) delete_Foo(self);
|
||||
}
|
||||
...
|
||||
// Ownership control API
|
||||
void disown() {
|
||||
thisown = 0;
|
||||
}
|
||||
void acquire() {
|
||||
thisown = 1;
|
||||
}
|
||||
FooProxy() {
|
||||
self = new_Foo();
|
||||
thisown = 1; // Newly created object
|
||||
}
|
||||
~FooProxy() {
|
||||
if (thisown) delete_Foo(self);
|
||||
}
|
||||
...
|
||||
// Ownership control API
|
||||
void disown() {
|
||||
thisown = 0;
|
||||
}
|
||||
void acquire() {
|
||||
thisown = 1;
|
||||
}
|
||||
};
|
||||
|
||||
class FooPtrProxy: public FooProxy {
|
||||
public:
|
||||
FooPtrProxy(Foo *s) {
|
||||
self = s;
|
||||
thisown = 0;
|
||||
}
|
||||
FooPtrProxy(Foo *s) {
|
||||
self = s;
|
||||
thisown = 0;
|
||||
}
|
||||
};
|
||||
|
||||
class SpamProxy {
|
||||
...
|
||||
FooProxy *value_get() {
|
||||
return FooPtrProxy(Spam_value_get(self));
|
||||
}
|
||||
void value_set(FooProxy *v) {
|
||||
Spam_value_set(self,v->self);
|
||||
v->disown();
|
||||
}
|
||||
...
|
||||
...
|
||||
FooProxy *value_get() {
|
||||
return FooPtrProxy(Spam_value_get(self));
|
||||
}
|
||||
void value_set(FooProxy *v) {
|
||||
Spam_value_set(self,v->self);
|
||||
v->disown();
|
||||
}
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -704,9 +704,9 @@ First, SWIG won't generate wrappers for protected or private constructors. For
|
|||
<pre>
|
||||
class Foo {
|
||||
protected:
|
||||
Foo(); // Not wrapped.
|
||||
Foo(); // Not wrapped.
|
||||
public:
|
||||
...
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -720,8 +720,8 @@ pure virtual methods. Here are some examples:
|
|||
<pre>
|
||||
class Bar {
|
||||
public:
|
||||
Bar(); // Not wrapped. Bar is abstract.
|
||||
virtual void spam(void) = 0;
|
||||
Bar(); // Not wrapped. Bar is abstract.
|
||||
virtual void spam(void) = 0;
|
||||
};
|
||||
|
||||
class Grok : public Bar {
|
||||
|
|
@ -754,8 +754,8 @@ non-abstract using this:
|
|||
|
||||
class Foo : public Bar {
|
||||
public:
|
||||
Foo(); // Generated no matter what---not abstract.
|
||||
...
|
||||
Foo(); // Generated no matter what---not abstract.
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -948,9 +948,9 @@ Alternatively, you can specify an immutable member in advance like this:
|
|||
%immutable List::length;
|
||||
...
|
||||
class List {
|
||||
...
|
||||
int length; // Immutable by above directive
|
||||
...
|
||||
...
|
||||
int length; // Immutable by above directive
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1078,7 +1078,7 @@ like this
|
|||
<div class="code">
|
||||
<pre>
|
||||
struct Foo {
|
||||
size_t len;
|
||||
size_t len;
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1176,10 +1176,10 @@ The following example illustrates this:
|
|||
<pre>
|
||||
class Foo {
|
||||
private:
|
||||
static const int spam;
|
||||
static const int spam;
|
||||
public:
|
||||
void bar(int x, int y = spam); // Won't work with %feature("compactdefaultargs") -
|
||||
// private default value
|
||||
void bar(int x, int y = spam); // Won't work with %feature("compactdefaultargs") -
|
||||
// private default value
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1262,9 +1262,9 @@ you have this code:
|
|||
<pre>
|
||||
class Foo {
|
||||
public:
|
||||
...
|
||||
friend void blah(Foo *f);
|
||||
...
|
||||
...
|
||||
friend void blah(Foo *f);
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1299,9 +1299,9 @@ namespace bar {
|
|||
|
||||
class Foo {
|
||||
public:
|
||||
...
|
||||
friend void blah(Foo *f);
|
||||
...
|
||||
...
|
||||
friend void blah(Foo *f);
|
||||
...
|
||||
};
|
||||
}
|
||||
</pre>
|
||||
|
|
@ -1364,7 +1364,7 @@ For example:
|
|||
<div class="code"><pre>
|
||||
class Bar {
|
||||
public:
|
||||
Foo &spam();
|
||||
Foo &spam();
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1376,8 +1376,8 @@ Generates an accessor like this:
|
|||
<div class="code">
|
||||
<pre>
|
||||
Foo *Bar_spam(Bar *obj) {
|
||||
Foo &result = obj->spam();
|
||||
return &result;
|
||||
Foo &result = obj->spam();
|
||||
return &result;
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1433,10 +1433,10 @@ following:
|
|||
<div class="code">
|
||||
<pre>
|
||||
Vector *wrap_cross_product(Vector *a, Vector *b) {
|
||||
Vector x = *a;
|
||||
Vector y = *b;
|
||||
Vector r = cross_product(x,y);
|
||||
return new Vector(r);
|
||||
Vector x = *a;
|
||||
Vector y = *b;
|
||||
Vector r = cross_product(x,y);
|
||||
return new Vector(r);
|
||||
}</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -1455,10 +1455,10 @@ called the "Fulton Transform". This produces a wrapper that looks like this:
|
|||
<div class="code">
|
||||
<pre>
|
||||
Vector cross_product(Vector *a, Vector *b) {
|
||||
SwigValueWrapper<Vector> x = *a;
|
||||
SwigValueWrapper<Vector> y = *b;
|
||||
SwigValueWrapper<Vector> r = cross_product(x,y);
|
||||
return new Vector(r);
|
||||
SwigValueWrapper<Vector> x = *a;
|
||||
SwigValueWrapper<Vector> y = *b;
|
||||
SwigValueWrapper<Vector> r = cross_product(x,y);
|
||||
return new Vector(r);
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1672,7 +1672,7 @@ Similarly, <tt>typedef</tt> allows unnamed structures to be used as base classes
|
|||
<div class="code">
|
||||
<pre>
|
||||
typedef struct {
|
||||
...
|
||||
...
|
||||
} Foo;
|
||||
|
||||
class Bar : public Foo { // Ok.
|
||||
|
|
@ -1741,23 +1741,23 @@ inheritance. For example, suppose you had code like this:
|
|||
<pre>
|
||||
class A {
|
||||
public:
|
||||
int x;
|
||||
int x;
|
||||
};
|
||||
|
||||
class B {
|
||||
public:
|
||||
int y;
|
||||
int y;
|
||||
};
|
||||
|
||||
class C : public A, public B {
|
||||
};
|
||||
|
||||
int A_function(A *a) {
|
||||
return a->x;
|
||||
return a->x;
|
||||
}
|
||||
|
||||
int B_function(B *b) {
|
||||
return b->y;
|
||||
return b->y;
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1844,10 +1844,10 @@ constructors. For example, if you supply SWIG with overloaded functions like th
|
|||
<div class="code">
|
||||
<pre>
|
||||
void foo(int x) {
|
||||
printf("x is %d\n", x);
|
||||
printf("x is %d\n", x);
|
||||
}
|
||||
void foo(char *x) {
|
||||
printf("x is '%s'\n", x);
|
||||
printf("x is '%s'\n", x);
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1875,10 +1875,10 @@ this code,
|
|||
<pre>
|
||||
class Foo {
|
||||
public:
|
||||
Foo();
|
||||
Foo(const Foo &); // Copy constructor
|
||||
void bar(int x);
|
||||
void bar(char *s, int y);
|
||||
Foo();
|
||||
Foo(const Foo &); // Copy constructor
|
||||
void bar(int x);
|
||||
void bar(char *s, int y);
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2193,9 +2193,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>
|
||||
|
|
@ -2227,23 +2227,23 @@ an entire class hierarchy with only a few declarations. For example:
|
|||
|
||||
class Spam {
|
||||
public:
|
||||
virtual void foo(int); // Renamed to foo_i
|
||||
virtual void foo(double); // Renamed to foo_d
|
||||
...
|
||||
virtual void foo(int); // Renamed to foo_i
|
||||
virtual void foo(double); // Renamed to foo_d
|
||||
...
|
||||
};
|
||||
|
||||
class Bar : public Spam {
|
||||
public:
|
||||
virtual void foo(int); // Renamed to foo_i
|
||||
virtual void foo(double); // Renamed to foo_d
|
||||
...
|
||||
virtual void foo(int); // Renamed to foo_i
|
||||
virtual void foo(double); // Renamed to foo_d
|
||||
...
|
||||
};
|
||||
|
||||
class Grok : public Bar {
|
||||
public:
|
||||
virtual void foo(int); // Renamed to foo_i
|
||||
virtual void foo(double); // Renamed to foo_d
|
||||
...
|
||||
virtual void foo(int); // Renamed to foo_i
|
||||
virtual void foo(double); // Renamed to foo_d
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2256,18 +2256,18 @@ class definition itself. For example:
|
|||
<div class="code">
|
||||
<pre>
|
||||
class Spam {
|
||||
%rename(foo_i) foo(int);
|
||||
%rename(foo_d) foo(double);
|
||||
%rename(foo_i) foo(int);
|
||||
%rename(foo_d) foo(double);
|
||||
public:
|
||||
virtual void foo(int); // Renamed to foo_i
|
||||
virtual void foo(double); // Renamed to foo_d
|
||||
...
|
||||
virtual void foo(int); // Renamed to foo_i
|
||||
virtual void foo(double); // Renamed to foo_d
|
||||
...
|
||||
};
|
||||
|
||||
class Bar : public Spam {
|
||||
public:
|
||||
virtual void foo(int); // Renamed to foo_i
|
||||
virtual void foo(double); // Renamed to foo_d
|
||||
virtual void foo(int); // Renamed to foo_i
|
||||
virtual void foo(double); // Renamed to foo_d
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
|
|
@ -2406,9 +2406,9 @@ For example, if you have a class like this:</p>
|
|||
<pre>
|
||||
class Spam {
|
||||
public:
|
||||
...
|
||||
void bar() const;
|
||||
...
|
||||
...
|
||||
void bar() const;
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2443,10 +2443,10 @@ that differ only in their qualifiers, like this:
|
|||
<pre>
|
||||
class Spam {
|
||||
public:
|
||||
...
|
||||
void bar(); // Unqualified member
|
||||
void bar() const; // Qualified member
|
||||
...
|
||||
...
|
||||
void bar(); // Unqualified member
|
||||
void bar() const; // Qualified member
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2492,11 +2492,11 @@ typedef int Integer;
|
|||
|
||||
class Spam {
|
||||
public:
|
||||
void foo(Integer); // Stays 'foo' (not renamed)
|
||||
void foo(Integer); // Stays 'foo' (not renamed)
|
||||
};
|
||||
class Ham {
|
||||
public:
|
||||
void foo(int); // Renamed to foo_i
|
||||
void foo(int); // Renamed to foo_i
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2511,9 +2511,9 @@ Let's consider the following example class:</p>
|
|||
<pre>
|
||||
class Spam {
|
||||
public:
|
||||
...
|
||||
void bar(int i=-1, double d=0.0);
|
||||
...
|
||||
...
|
||||
void bar(int i=-1, double d=0.0);
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2660,9 +2660,9 @@ something like this pseudocode:
|
|||
<div class="code">
|
||||
<pre>
|
||||
_wrap_Complex___add__(args) {
|
||||
... get args ...
|
||||
obj->operator+(args);
|
||||
...
|
||||
... get args ...
|
||||
obj->operator+(args);
|
||||
...
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3126,7 +3126,7 @@ For example, if you wrote code like this,
|
|||
%template(intList) List<int>;
|
||||
...
|
||||
class UltraList : public List<int> {
|
||||
...
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3314,8 +3314,8 @@ look like this:
|
|||
<pre>
|
||||
class Foo {
|
||||
public:
|
||||
template<class T> void bar(T x, T y) { ... };
|
||||
...
|
||||
template<class T> void bar(T x, T y) { ... };
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3328,10 +3328,10 @@ To expand the template, simply use <tt>%template</tt> inside the class.
|
|||
<pre>
|
||||
class Foo {
|
||||
public:
|
||||
template<class T> void bar(T x, T y) { ... };
|
||||
...
|
||||
%template(barint) bar<int>;
|
||||
%template(bardouble) bar<double>;
|
||||
template<class T> void bar(T x, T y) { ... };
|
||||
...
|
||||
%template(barint) bar<int>;
|
||||
%template(bardouble) bar<double>;
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3344,13 +3344,13 @@ Or, if you want to leave the original class definition alone, just do this:
|
|||
<pre>
|
||||
class Foo {
|
||||
public:
|
||||
template<class T> void bar(T x, T y) { ... };
|
||||
...
|
||||
template<class T> void bar(T x, T y) { ... };
|
||||
...
|
||||
};
|
||||
...
|
||||
%extend Foo {
|
||||
%template(barint) bar<int>;
|
||||
%template(bardouble) bar<double>;
|
||||
%template(barint) bar<int>;
|
||||
%template(bardouble) bar<double>;
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3363,8 +3363,8 @@ or simply
|
|||
<pre>
|
||||
class Foo {
|
||||
public:
|
||||
template<class T> void bar(T x, T y) { ... };
|
||||
...
|
||||
template<class T> void bar(T x, T y) { ... };
|
||||
...
|
||||
};
|
||||
...
|
||||
|
||||
|
|
@ -3413,9 +3413,9 @@ template class. Here is a slightly perverse example:
|
|||
// A template
|
||||
template<class T> class Foo {
|
||||
public:
|
||||
// A member template
|
||||
template<class S> T bar(S x, S y) { ... };
|
||||
...
|
||||
// A member template
|
||||
template<class S> T bar(S x, S y) { ... };
|
||||
...
|
||||
};
|
||||
|
||||
// Expand a few member templates
|
||||
|
|
@ -3443,12 +3443,12 @@ and conversions. For example:
|
|||
<div class="code">
|
||||
<pre>
|
||||
template<class T1, class T2> struct pair {
|
||||
T1 first;
|
||||
T2 second;
|
||||
pair() : first(T1()), second(T2()) { }
|
||||
pair(const T1 &x, const T2 &y) : first(x), second(y) { }
|
||||
template<class U1, class U2> pair(const pair<U1,U2> &x)
|
||||
: first(x.first),second(x.second) { }
|
||||
T1 first;
|
||||
T2 second;
|
||||
pair() : first(T1()), second(T2()) { }
|
||||
pair(const T1 &x, const T2 &y) : first(x), second(y) { }
|
||||
template<class U1, class U2> pair(const pair<U1,U2> &x)
|
||||
: first(x.first),second(x.second) { }
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3462,7 +3462,7 @@ in the template class itself. For example:
|
|||
<div class="code">
|
||||
<pre>
|
||||
%extend pair {
|
||||
%template(pair) pair<T1,T2>; // Generate default copy constructor
|
||||
%template(pair) pair<T1,T2>; // Generate default copy constructor
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3484,13 +3484,13 @@ Alternatively, you could expand the constructor template in selected instantiati
|
|||
|
||||
// Create a default constructor only
|
||||
%extend pair<int,int> {
|
||||
%template(paird) pair<int,int>; // Default constructor
|
||||
%template(paird) pair<int,int>; // Default constructor
|
||||
};
|
||||
|
||||
// Create default and conversion constructors
|
||||
%extend pair<double,double> {
|
||||
%template(paird) pair<double,dobule>; // Default constructor
|
||||
%template(pairc) pair<int,int>; // Conversion constructor
|
||||
%template(paird) pair<double,dobule>; // Default constructor
|
||||
%template(pairc) pair<int,int>; // Conversion constructor
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3504,8 +3504,8 @@ instead:
|
|||
<pre>
|
||||
// Create default and conversion constructors
|
||||
%extend pair<double,double> {
|
||||
%template(pair) pair<double,dobule>; // Default constructor
|
||||
%template(pair) pair<int,int>; // Conversion constructor
|
||||
%template(pair) pair<double,dobule>; // Default constructor
|
||||
%template(pair) pair<int,int>; // Conversion constructor
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3527,19 +3527,19 @@ included directly in template definitions. For example:
|
|||
<div class="code"><pre>
|
||||
// File : list.h
|
||||
template<class T> class List {
|
||||
...
|
||||
...
|
||||
public:
|
||||
%rename(__getitem__) get(int);
|
||||
List(int max);
|
||||
~List();
|
||||
...
|
||||
T get(int index);
|
||||
%extend {
|
||||
char *__str__() {
|
||||
/* Make a string representation */
|
||||
...
|
||||
}
|
||||
%rename(__getitem__) get(int);
|
||||
List(int max);
|
||||
~List();
|
||||
...
|
||||
T get(int index);
|
||||
%extend {
|
||||
char *__str__() {
|
||||
/* Make a string representation */
|
||||
...
|
||||
}
|
||||
}
|
||||
};
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -3556,14 +3556,14 @@ It is also possible to separate these declarations from the template class. For
|
|||
<pre>
|
||||
%rename(__getitem__) List::get;
|
||||
%extend List {
|
||||
char *__str__() {
|
||||
/* Make a string representation */
|
||||
...
|
||||
}
|
||||
/* Make a copy */
|
||||
T *__copy__() {
|
||||
return new List<T>(*$self);
|
||||
}
|
||||
char *__str__() {
|
||||
/* Make a string representation */
|
||||
...
|
||||
}
|
||||
/* Make a copy */
|
||||
T *__copy__() {
|
||||
return new List<T>(*$self);
|
||||
}
|
||||
};
|
||||
|
||||
...
|
||||
|
|
@ -3722,15 +3722,15 @@ encapsulate common functionality. For example:
|
|||
<div class="code">
|
||||
<pre>
|
||||
namespace math {
|
||||
double sin(double);
|
||||
double cos(double);
|
||||
double sin(double);
|
||||
double cos(double);
|
||||
|
||||
class Complex {
|
||||
double im,re;
|
||||
public:
|
||||
...
|
||||
};
|
||||
...
|
||||
class Complex {
|
||||
double im,re;
|
||||
public:
|
||||
...
|
||||
};
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3798,18 +3798,18 @@ namespace A {
|
|||
}
|
||||
|
||||
namespace B {
|
||||
namespace C {
|
||||
using namespace A;
|
||||
}
|
||||
typedef C::Foo FooClass;
|
||||
namespace C {
|
||||
using namespace A;
|
||||
}
|
||||
typedef C::Foo FooClass;
|
||||
}
|
||||
|
||||
namespace BIGB = B;
|
||||
|
||||
namespace D {
|
||||
using BIGB::FooClass;
|
||||
class Bar : public FooClass {
|
||||
}
|
||||
using BIGB::FooClass;
|
||||
class Bar : public FooClass {
|
||||
}
|
||||
};
|
||||
|
||||
class Spam : public D::Bar {
|
||||
|
|
@ -3843,12 +3843,12 @@ you have code like this,
|
|||
<pre>
|
||||
%module foo
|
||||
namespace foo {
|
||||
void bar(int);
|
||||
void spam();
|
||||
void bar(int);
|
||||
void spam();
|
||||
}
|
||||
|
||||
namespace bar {
|
||||
void blah();
|
||||
void blah();
|
||||
}
|
||||
|
||||
</pre>
|
||||
|
|
@ -3882,10 +3882,10 @@ namespaces to generate a name conflict in the target language. For example:
|
|||
<div class="code">
|
||||
<pre>
|
||||
namespace A {
|
||||
void foo(int);
|
||||
void foo(int);
|
||||
}
|
||||
namespace B {
|
||||
void foo(double);
|
||||
void foo(double);
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3910,10 +3910,10 @@ To resolve this error, simply use <tt>%rename</tt> to disambiguate the declarati
|
|||
%rename(B_foo) B::foo;
|
||||
...
|
||||
namespace A {
|
||||
void foo(int);
|
||||
void foo(int);
|
||||
}
|
||||
namespace B {
|
||||
void foo(double); // Gets renamed to B_foo
|
||||
void foo(double); // Gets renamed to B_foo
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3932,7 +3932,7 @@ system to track type-names. Therefore, if you have code like this:
|
|||
<div class="code">
|
||||
<pre>
|
||||
namespace A {
|
||||
typedef int Integer;
|
||||
typedef int Integer;
|
||||
}
|
||||
using namespace A;
|
||||
void foo(Integer x);
|
||||
|
|
@ -3981,18 +3981,18 @@ typemaps, exception handlers, and so forth. For example, consider the following
|
|||
<div class="code">
|
||||
<pre>
|
||||
namespace foo {
|
||||
typedef int Integer;
|
||||
class bar {
|
||||
typedef int Integer;
|
||||
class bar {
|
||||
public:
|
||||
...
|
||||
};
|
||||
...
|
||||
};
|
||||
}
|
||||
|
||||
%extend foo::bar {
|
||||
Integer add(Integer x, Integer y) {
|
||||
Integer r = x + y; // Error. Integer not defined in this scope
|
||||
return r;
|
||||
}
|
||||
Integer add(Integer x, Integer y) {
|
||||
Integer r = x + y; // Error. Integer not defined in this scope
|
||||
return r;
|
||||
}
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -4007,10 +4007,10 @@ To fix the problem, make sure you use fully qualified names. For example:
|
|||
<div class="code">
|
||||
<pre>
|
||||
%extend foo::bar {
|
||||
Integer add(Integer x, Integer y) {
|
||||
foo::Integer r = x + y; // Ok.
|
||||
return r;
|
||||
}
|
||||
Integer add(Integer x, Integer y) {
|
||||
foo::Integer r = x + y; // Ok.
|
||||
return r;
|
||||
}
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -4037,17 +4037,17 @@ these directives, consider the following:
|
|||
// Good version
|
||||
%inline %{
|
||||
namespace foo {
|
||||
void bar(int) { ... }
|
||||
...
|
||||
void bar(int) { ... }
|
||||
...
|
||||
}
|
||||
%}
|
||||
|
||||
// Bad version. Emitted code not placed in namespace.
|
||||
namespace foo {
|
||||
%inline %{
|
||||
void bar(int) { ... } /* I'm bad */
|
||||
...
|
||||
%}
|
||||
void bar(int) { ... } /* I'm bad */
|
||||
...
|
||||
%}
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -4060,12 +4060,12 @@ included in the generated functions. For example, if you have code like this,
|
|||
<div class="code">
|
||||
<pre>
|
||||
namespace foo {
|
||||
class bar {
|
||||
public:
|
||||
%extend {
|
||||
int blah(int x);
|
||||
};
|
||||
};
|
||||
class bar {
|
||||
public:
|
||||
%extend {
|
||||
int blah(int x);
|
||||
};
|
||||
};
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -4088,13 +4088,13 @@ conflicts in the input, there will be no conflicts in the generated code.
|
|||
<div class="code">
|
||||
<pre>
|
||||
namespace foo {
|
||||
class bar;
|
||||
class spam {
|
||||
public:
|
||||
...
|
||||
operator bar(); // Conversion of spam -> bar
|
||||
...
|
||||
};
|
||||
class bar;
|
||||
class spam {
|
||||
public:
|
||||
...
|
||||
operator bar(); // Conversion of spam -> bar
|
||||
...
|
||||
};
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -4128,13 +4128,13 @@ Note, however, that if the operator is defined using a qualifier in its name, th
|
|||
%rename(tofoo) foo::spam::operator bar(); // will not match
|
||||
%rename(tofoo) foo::spam::operator foo::bar(); // will match
|
||||
namespace foo {
|
||||
class bar;
|
||||
class spam {
|
||||
public:
|
||||
...
|
||||
operator foo::bar();
|
||||
...
|
||||
};
|
||||
class bar;
|
||||
class spam {
|
||||
public:
|
||||
...
|
||||
operator foo::bar();
|
||||
...
|
||||
};
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -4346,7 +4346,7 @@ f = Foo()
|
|||
try:
|
||||
f.blah()
|
||||
except Error,e:
|
||||
# e is a wrapped instance of "Error"
|
||||
# e is a wrapped instance of "Error"
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -4550,13 +4550,13 @@ code produces wrappers like this:
|
|||
<div class="code">
|
||||
<pre>
|
||||
int Foo_x_get(Foo *f) {
|
||||
return (*f)->x;
|
||||
return (*f)->x;
|
||||
}
|
||||
void Foo_x_set(Foo *f, int value) {
|
||||
(*f)->x = value;
|
||||
(*f)->x = value;
|
||||
}
|
||||
void Foo_bar(Foo *f) {
|
||||
(*f)->bar();
|
||||
(*f)->bar();
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -4636,8 +4636,8 @@ class Foo { // Ignored
|
|||
|
||||
class Bar {
|
||||
public:
|
||||
Foo *operator->();
|
||||
...
|
||||
Foo *operator->();
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -4785,14 +4785,14 @@ different to any other regular instance:
|
|||
<div class="targetlang">
|
||||
<pre>
|
||||
def create_A():
|
||||
a = A() # SWIG ref 'a' - new object is passed to python (count: 1)
|
||||
b1 = B(a) # C++ ref 'a (count: 2)
|
||||
if 1 + 1 == 2:
|
||||
b2 = B(a) # C++ ref 'a' (count: 3)
|
||||
return a # 'b1' and 'b2' are released and deleted, C++ unref 'a' twice (count: 1)
|
||||
a = A() # SWIG ref 'a' - new object is passed to python (count: 1)
|
||||
b1 = B(a) # C++ ref 'a (count: 2)
|
||||
if 1 + 1 == 2:
|
||||
b2 = B(a) # C++ ref 'a' (count: 3)
|
||||
return a # 'b1' and 'b2' are released and deleted, C++ unref 'a' twice (count: 1)
|
||||
|
||||
a = create_A() # (count: 1)
|
||||
exit # 'a' is released, SWIG unref 'a' called in the destructor wrapper (count: 0)
|
||||
a = create_A() # (count: 1)
|
||||
exit # 'a' is released, SWIG unref 'a' called in the destructor wrapper (count: 0)
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -4976,14 +4976,14 @@ won't cause a conflict. For example:</p>
|
|||
<pre>
|
||||
class Foo {
|
||||
public:
|
||||
int blah(int );
|
||||
double blah(double);
|
||||
int blah(int );
|
||||
double blah(double);
|
||||
};
|
||||
|
||||
class Bar : public Foo {
|
||||
public:
|
||||
using Foo::blah; // Only imports blah(double);
|
||||
int blah(int);
|
||||
using Foo::blah; // Only imports blah(double);
|
||||
int blah(int);
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -4997,14 +4997,14 @@ imported by <tt>using</tt>. For example:
|
|||
%rename(blah_long) Foo::blah(long);
|
||||
class Foo {
|
||||
public:
|
||||
int blah(int);
|
||||
long blah(long); // Renamed to blah_long
|
||||
int blah(int);
|
||||
long blah(long); // Renamed to blah_long
|
||||
};
|
||||
|
||||
class Bar : public Foo {
|
||||
public:
|
||||
using Foo::blah; // Only imports blah(int)
|
||||
double blah(double x);
|
||||
using Foo::blah; // Only imports blah(int)
|
||||
double blah(double x);
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -5101,7 +5101,7 @@ void bar(Object *);
|
|||
...
|
||||
// C++ code
|
||||
void blah() {
|
||||
bar(foo()); // Error: bar discards const
|
||||
bar(foo()); // Error: bar discards const
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -443,14 +443,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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
@ -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,12 +1730,12 @@ 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();
|
||||
};
|
||||
|
||||
|
|
@ -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() {
|
||||
|
|
@ -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;
|
||||
$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>
|
||||
|
|
@ -3105,7 +3103,7 @@ 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_ConvertPtr($input,(void **) &$1, $1_descriptor,0)) == -1) return NULL;
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3118,7 +3116,7 @@ For example:
|
|||
<div class="indent">
|
||||
<pre>
|
||||
%typemap(in) Foo * {
|
||||
if ((SWIG_ConvertPtr($input,(void **) &$1, $descriptor(Foo *), 0)) == -1) return NULL;
|
||||
if ((SWIG_ConvertPtr($input,(void **) &$1, $descriptor(Foo *), 0)) == -1) return NULL;
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -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>
|
||||
|
|
@ -525,16 +525,16 @@ like this:
|
|||
%#if PY_VERSION_HEX>=0x03000000
|
||||
PyObject *pystr;
|
||||
if (!PyUnicode_Check(pyobj)) {
|
||||
PyErr_SetString(PyExc_ValueError, "Expected a string");
|
||||
SWIG_fail;
|
||||
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");
|
||||
SWIG_fail;
|
||||
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)) {
|
||||
free(argv);
|
||||
PyErr_SetString(PyExc_ValueError,"Expected a string");
|
||||
SWIG_fail;
|
||||
}
|
||||
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 */
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue