wiki:pjsua2/SWIG_Quirks

Version 5 (modified by bennylp, 12 years ago) (diff)

--

SWIG Quirks

TracNav

  • TOC "pjsua2/TOC" is empty!

Table of Contents

  1. Common
    1. Quirks with the use of namespace
    2. No pass by reference
    3. "const" in parameter matters
    4. Must use exception specification in C++ functions
    5. Undeclared types will be (silently) converted to pointer
  2. Python
    1. std::vector as attributes doesn't work as expected
  3. Java
    1. Java attributes: none of them!
    2. No mapping between std::vector to Java array


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
  }
}