Python 的 C++ 库的 SWIG 包装器 - 子模块
SWIG wrapper of C++ library for Python - submodules
我正在尝试使用 SWIG 将 C++ 库包装到 Python3 接口中,但有一个问题我无法完全解决。这个库有几个命名空间,我想在包装在 Python 中时使它们成为库的模块。假设以下最小示例:
lib_class.hpp lib_class.cpp
lib_ops.hpp lib_ops.cpp
io_ops.hpp io_ops.cpp
文件lib_class
定义了一个非常小的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; }
}
文件lib_ops.hpp
和lib_ops.cpp
只定义了一个函数:
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;
}
}
最后是文件 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();
}
}
}
我想将这些文件包装到一个 Python 界面中,这样我就可以:
import lib
d = lib.dummy(10)
lib.ioop.io_operation(d)
lib.lib_operation()
换句话说,我希望 Python 包装器的组织是:
lib.dummy # class
lib.lib_operation # function
lib.ioop # submodule
lib.ioop.io_operation # function within submodule
我编写了以下 *.i
个文件:
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"
编译没有错误:
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
然而,上面的 python 脚本给出了以下错误:
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 &'
尽管我设法 "insert" 命名空间 lib::io
进入 "main" 模块 lib
作为子模块 ioop
,但看起来好像没有'我对 class lib::dummy
.
一无所知
这可以吗?如果可以,我该怎么做?
感谢大家的宝贵时间(很抱歉这么长post)。
正如@Flexo 在其中一条评论中指出的那样,文件 ioops.i
需要一个 %import
。文件的正确内容是:
%module ioop
%import lib.i
%{
#include "io_ops.hpp"
using namespace lib;
%}
%include "io_ops.hpp"
我正在尝试使用 SWIG 将 C++ 库包装到 Python3 接口中,但有一个问题我无法完全解决。这个库有几个命名空间,我想在包装在 Python 中时使它们成为库的模块。假设以下最小示例:
lib_class.hpp lib_class.cpp
lib_ops.hpp lib_ops.cpp
io_ops.hpp io_ops.cpp
文件lib_class
定义了一个非常小的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; }
}
文件lib_ops.hpp
和lib_ops.cpp
只定义了一个函数:
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;
}
}
最后是文件 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();
}
}
}
我想将这些文件包装到一个 Python 界面中,这样我就可以:
import lib
d = lib.dummy(10)
lib.ioop.io_operation(d)
lib.lib_operation()
换句话说,我希望 Python 包装器的组织是:
lib.dummy # class
lib.lib_operation # function
lib.ioop # submodule
lib.ioop.io_operation # function within submodule
我编写了以下 *.i
个文件:
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"
编译没有错误:
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
然而,上面的 python 脚本给出了以下错误:
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 &'
尽管我设法 "insert" 命名空间 lib::io
进入 "main" 模块 lib
作为子模块 ioop
,但看起来好像没有'我对 class lib::dummy
.
这可以吗?如果可以,我该怎么做?
感谢大家的宝贵时间(很抱歉这么长post)。
正如@Flexo 在其中一条评论中指出的那样,文件 ioops.i
需要一个 %import
。文件的正确内容是:
%module ioop
%import lib.i
%{
#include "io_ops.hpp"
using namespace lib;
%}
%include "io_ops.hpp"