Version 5 (modified by bennylp, 12 years ago) (diff) |
---|
SWIG Quirks
TracNav
- TOC "pjsua2/TOC" is empty!
Table of Contents
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<string> my_array1; // this is recognized as pj::vector<pj::string> vector<std::string> my_array2; // this is recognized as pj::vector<std::string> }
It works after adding std:
using std::vector; using std::string; string my_string; // ok vector<int> my_array; // vector<int> is okay though! std::vector<std::string> my_array; // now it's ok too
No pass by reference
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<int> & param ); void func_b( vector<int> & 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 <pj/types.h> 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 <pj/types.h> 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<int> &data); std::vector<int> 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<int> my_values; };
// example.i %module example %{ #include “example.h” %} %include "std_string.i" %include "std_vector.i" namespace std { %template(IntVector) std::vector<int>; } %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!
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 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<std::string> &arr) {}
// ua.i %module ua %{ #include "ua.h" %} %include "std_string.i" %include "std_vector.i" namespace std { %template(StringVector) std::vector<std::string>; } %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 } }