Reputation: 1243
I'm trying to wrap a C++ library into a Python3 interface using SWIG, and there is a problem I can't quite fix. This library has several namespaces, and I would like to make them modules of the library when wrapped in Python. Assume the following minimal example:
lib_class.hpp lib_class.cpp
lib_ops.hpp lib_ops.cpp
io_ops.hpp io_ops.cpp
The files lib_class
define a very small class:
lib_class.hpp
#pragma once
namespace lib {
class dummy {
private:
int a;
public:
dummy();
dummy(int t_a);
~dummy();
void asdf();
};
}
lib_class.cpp
#include "lib_class.hpp"
namespace lib {
dummy::dummy() {}
dummy::dummy(int t_a) : a(t_a) {}
dummy::~dummy() {}
void dummy::asdf() { a = 3; }
}
The files lib_ops.hpp
and lib_ops.cpp
define a only one function:
lib_ops.hpp
:#pragma once
namespace lib {
void lib_operation();
}
lib_ops.cpp
:#include "lib_ops.hpp"
#include <iostream>
using namespace std;
namespace lib {
void lib_operation() {
cout << "LIBRARY TOP LEVEL" << endl;
}
}
and, finally, the files io_ops.hpp
io_ops.cppdefine another function, this time within the namespace
lib::io```:
io_ops.hpp
#pragma once
#include "lib_class.hpp"
namespace lib {
namespace io {
void io_operation(dummy& a);
}
}
io_ops.cpp
#include "io_ops.hpp"
#include <iostream>
using namespace std;
namespace lib {
namespace io {
void io_operation(dummy& a) {
cout << "LIBRARY SUBMODULE" << endl;
a.asdf();
}
}
}
I would like to wrap these files into a Python interface so that I can:
import lib
d = lib.dummy(10)
lib.ioop.io_operation(d)
lib.lib_operation()
In other words, I would like the organization of the Python wrapper to be:
lib.dummy # class
lib.lib_operation # function
lib.ioop # submodule
lib.ioop.io_operation # function within submodule
I've written the following *.i
files:
lib.i
:%module lib
%import ioop.i
%{
#include "lib_ops.hpp"
#include "lib_class.hpp"
%}
%include "lib_ops.hpp"
%include "lib_class.hpp"
ioop.i
:%module ioop
%{
#include "io_ops.hpp"
using namespace lib;
%}
%include "io_ops.hpp"
This compiles without errors with:
g++ -c -fPIC io_ops.cpp
g++ -c -fPIC lib_ops.cpp
g++ -c -fPIC lib_class.cpp
swig -c++ -python -py3 lib.i
swig -c++ -python -py3 ioop.i
g++ -fPIC -c lib_wrap.cxx -I /usr/include/python3.6
g++ -fPIC -c ioop_wrap.cxx -I /usr/include/python3.6
g++ -fPIC -shared -o _lib.so lib_wrap.o lib_ops.o lib_class.o
g++ -fPIC -shared -o _ioop.so ioop_wrap.o io_ops.o lib_class.o
however, the python script above gives the following error:
Traceback (most recent call last):
File "test.py3", line 5, in <module>
lib.ioop.io_operation(d)
File "/home/lluis/Desktop/example.i/ioop.py", line 66, in io_operation
return _ioop.io_operation(a)
TypeError: in method 'io_operation', argument 1 of type 'dummy &'
Although I managed to "insert" the namespace lib::io
into the "main" module lib
as a submodule ioop
, it looks as though it didn't know anything about the class lib::dummy
.
Is it possible to do this? If so, how can I do it?
Thanks to all of you for your time (and sorry for such a lengthy post).
Upvotes: 1
Views: 790
Reputation: 1243
As @Flexo pointed out in one of the comments, the file ioops.i
needs an %import
. The correct contents of the file are:
%module ioop
%import lib.i
%{
#include "io_ops.hpp"
using namespace lib;
%}
%include "io_ops.hpp"
Upvotes: 1