【问题标题】:How can I correctly create a C++ vector in Python3 by swig?如何通过 swig 在 Python3 中正确创建 C++ 向量?
【发布时间】:2022-01-22 10:52:05
【问题描述】:

我尝试测试 swig 库“std_vector.i”,但我无法像官方演示那样在 Python3 中创建矢量,这里有一些信息。

swig_test.i

%module swig_test

%{
#include <vector>
void worker(std::vector<int> &v) {
    v.push_back(123);
}
%}

%include <std_vector.i>
%template(MyVector) std::vector<int>;

void worker(std::vector<int> &v);

然后我运行:

swig -python -py3 -c++ swig_test.i

它工作正常。 然后是 setup.py

from distutils.core import setup, Extension

test_module = Extension('_swig_test',
                           sources=['swig_test_wrap.cxx'],
                           )

setup(name = 'swig_test',
       version = '0.1',
       author      = "SWIG Docs",
       description = """Simple swig test from docs""",
       ext_modules = [test_module],
       py_modules = ["swig_test"],)

然后运行:

python setup.py build_ext --inplace

它创建文件'_swig_test.cp38-win_amd64.pyd',我在shell中测试它。

>>> import _swig_test
>>> v = _swig_test.MyVector([1,2,3])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module '_swig_test' has no attribute 'MyVector'

太奇怪了,不能正常工作,然后我运行dir

>>> dir(_swig_test)
['MyVector___bool__', 'MyVector___delitem__', 'MyVector___delslice__', 'MyVector___getitem__', 'MyVector___getslice__', 'MyVector___len__', 'MyVector___nonzero__', 'MyVector___setitem__', 'MyVector___setslice__', 'MyVector_append', 'MyVector_assign', 'MyVector_back', 'MyVector_begin', 'MyVector_capacity', 'MyVector_clear', 'MyVector_empty', 'MyVector_end', 'MyVector_erase', 'MyVector_front', 'MyVector_get_allocator', 'MyVector_insert', 'MyVector_iterator', 'MyVector_pop', 'MyVector_pop_back', 'MyVector_push_back', 'MyVector_rbegin', 'MyVector_rend', 'MyVector_reserve', 'MyVector_resize', 'MyVector_size', 'MyVector_swap', 'MyVector_swiginit', 'MyVector_swigregister', 'SWIG_PyInstanceMethod_New', 'SwigPyIterator___add__', 'SwigPyIterator___eq__', 'SwigPyIterator___iadd__', 'SwigPyIterator___isub__', 'SwigPyIterator___ne__', 'SwigPyIterator___next__', 'SwigPyIterator___sub__', 'SwigPyIterator_advance', 'SwigPyIterator_copy', 'SwigPyIterator_decr', 'SwigPyIterator_distance', 'SwigPyIterator_equal', 'SwigPyIterator_incr', 'SwigPyIterator_next', 'SwigPyIterator_previous', 'SwigPyIterator_swigregister', 'SwigPyIterator_value', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'delete_MyVector', 'delete_SwigPyIterator', 'new_MyVector', 'worker']

我尝试添加#define SWIG_FILE_WITH_INIT,但没有任何用处,我尝试模仿官方demo,结果相同。

我该如何处理?

【问题讨论】:

  • (顺便说一句,这是一个很好的例子,说明如何提出一个体面的第一个问题 - 了解您所做的事情和您所处的位置所需的一切都简洁地预设了)

标签: python c++ swig


【解决方案1】:

这里的问题是您如何导入和使用已构建的模块。

当您运行 SWIG 并生成一些 C++ 代码时,它也生成了一些 Python。而不是直接访问您想通过生成的python访问它的本机模块,例如

import swig_test # Note no leading _
v = swig_test.MyVector([1,2,3])

这样就可以了。

请注意,您还可以通过使用 -builtin 标志调用 SWIG 来要求 SWIG 生成纯本机模块,例如:

swig -python -py3 -c++ -builtin swig_test.i

但是我通常不会在开始时推荐这个,因为它会使一堆常见的事情变得更加困难。

【讨论】:

  • 非常感谢!这意味着我应该导入.py文件(它仍然需要.pyd文件)而不是直接导入.pyd文件?
  • 正确 - 如果您导入 .py 文件,那么它应该会自动为您导入本机代码
猜你喜欢
  • 1970-01-01
  • 2021-03-26
  • 2010-10-08
  • 2015-10-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-28
相关资源
最近更新 更多