c++ - 用于 Python 的 C++ 库的 SWIG 包装器 - 子模块

标签 c++ python-3.x g++ swig

我正在尝试使用 SWIG 将 C++ 库包装到 Python3 接口(interface)中,但有一个问题我无法完全解决。这个库有几个命名空间,当用 Python 包装时,我想使它们成为库的模块。假设以下最小示例:

lib_class.hpp lib_class.cpp
lib_ops.hpp   lib_ops.cpp
io_ops.hpp    io_ops.cpp

lib_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.hpplib_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.cpp定义了另一个函数,这次是在命名空间内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 接口(interface)中,这样我就可以:

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 &'

尽管我设法将命名空间 lib::io 作为子模块 ioop“插入”到“主”模块 lib 中,但它看起来好像它对 lib::dummy 类一无所知。

这有可能吗?如果可以,我该怎么做?

感谢大家抽出宝贵时间(很抱歉发了这么长的帖子)。

最佳答案

正如@Flexo 在评论之一中指出的那样,文件ioops.i 需要一个%import。文件的正确内容是:

%module ioop
%import lib.i
%{
#include "io_ops.hpp"
using namespace lib;
%}
%include "io_ops.hpp"

关于c++ - 用于 Python 的 C++ 库的 SWIG 包装器 - 子模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58542498/

相关文章:

c++ - 在 Eclipse Ubuntu 14 中执行 Python 代码时出现 pretty-print 错误

c++ - 几个 vector 的笛卡尔积

python-3.x - 获取 FastAPI 响应的内容长度

c++ - 禁用 g++ 的返回值优化

c++ - 处理 std::thread::hardware_concurrency()

python - 序列化 C++ 对象以通过套接字发送到 Python - 最佳方法?

c++ - 我的代码能否使用 'T' 或 'const T &' 特化,以可用者为准?

python - Asyncio 如何重用套接字

python - 为什么在 Python 3.6.x/2.7.x 中两个具有相同浮点值的不同变量使用相同的 id()?

linux - 如何解决共享库中 undefined reference ?