{{{ #!html
}}} = SWIG Quirks = [[TracNav(pjsua2/TOC)]] '''Table of Contents''' [[PageOutline(2-3,,inline)]] [[BR]] = SWIG Quirks = == Common == === Quirks with the use of namespace === my_array1 and my_array2 below are not recognized as vector of string: {{{ // example.h namespace pj { using std::vector; using std::string; vector my_array1; // this is recognized as pj::vector vector my_array2; // this is recognized as pj::vector } }}} It works after adding ''std'': {{{ using std::vector; using std::string; string my_string; // ok vector my_array; // vector is okay though! std::vector my_array; // now it's ok too }}} === No pass by reference === #byref Continue reading below. === "const" in parameter matters === Otherwise conversion from Python list to std::vector doesn't work. E.g.: {{{ // example.h class A { public: void func_a( const vector & param ); void func_b( vector & param ); }; }}} {{{ a.func_a( [0, 1, 2] ) # <-- OK a.func_b( [0, 1, 2] ) # <-- ERROR }}} === Must use exception specification in C++ functions === Otherwise SWIG will terminate the app when it catches unspecified exception. E.g.: {{{ // example.h void raise_1() throw(Error) { throw Error(); } void raise_2() { throw Error() } }}} {{{ # Python try: raise_1() except Error, e: pass # <-- OK try: raise_2() # <-- ERROR (SWIG terminates app), even with catch-anything except: pass }}} === Undeclared types will be (silently) converted to pointer === Yes we know that, but it will catch you anyway, so I'll mention it again here. {{{ // example.h #include class Error { public: pj_status_t status; string reason; Error(pj_status_t err, const string &res) : status(err), reason(res) {} }; }}} {{{ // example.i %module example %{ #include “example.h” %} %include “example.h” }}} {{{ # test.py err = pj.Error(-1, "Unknown error") print "%d" % err.status }}} The code above compiles fine, but pj_status_t will be treated as pointer to unknown structure by SWIG, because the declaration is in which is not included in example.i. Hence the Python code above will not print -1 but the pointer value of status. == Python == === std::vector as attributes doesn't work as expected === Using std::vector as function arguments or return value works fine, e.g.: {{{ // example.h class A { public: void assign_data( const std::vector &data); std::vector retrieve_data() const; }; }}} {{{ # Python import example a = example.A() a.assign_data( [0, 1, 2, 3] ) data = a.retrieve_data() print data # will print: [0, 1, 2, 3] as expected }}} But as class attributes, it doesn't work as expected: {{{ // example.h class A { public: vector my_values; }; }}} {{{ // example.i %module example %{ #include “example.h” %} %include "std_string.i" %include "std_vector.i" namespace std { %template(IntVector) std::vector; } %include “example.h” }}} {{{ # Python a = example.A() a.my_values = [0, 1, 2] # <-- ERROR a.my_values = example.IntVector([0, 1, 2]) # <-- OK }}} == Java == === Java attributes: none of them! === #javaattr C++ attributes will be converted to get/set functions in Java! E.g.: {{{ // example.h class A { public: int data; }; }}} The "data" member will be converted to "getData()" and "setData()" in Java. === No mapping between std::vector to Java array === Even after applying the patch in [http://sourceforge.net/tracker/?func=detail&aid=3393025&group_id=1645&atid=301645 this SWIG ticket], std::vector is still not mapped to Java array. So we're left with awkward syntax to pass an array: {{{ // ua.h void set_array(const std::vector &arr) {} }}} {{{ // ua.i %module ua %{ #include "ua.h" %} %include "std_string.i" %include "std_vector.i" namespace std { %template(StringVector) std::vector; } %include "ua.h" }}} {{{ // UaTest.java public class UaTest { static { System.loadLibrary("ua"); } public static void main(String argv[]) { String[] sarr = { "Hello", "world"}; StringVector sv = new StringVector(sarr); ua.set_array(sarr); // <=----- ERROR ua.set_array(sv); // <=------ OK } } }}} {{{ #!html
}}} {{{ #!html }}}