用 swig 包装 C++ 向量引用
wrapping c++ vector reference with swig
我一直在尝试使用 swig 包装函数采用向量引用(以启用修改)形式的 C++ 代码:
//cpp_code.cpp
void worker(vector<int> &v){
// do something
}
// cpp_code.i
/* File: cpp_code.i */
%module cpp_code
%include "std_vector.i"
%include "typemaps.i"
%{
#include "cpp_code.cpp"
%}
%template(MyVector) std::vector<int>;
//%template(MyVectorPtr) std::vector<int &>;
%include "cpp_code.cpp"
void worker(vector<int> &v);
如果我取消注释部分 //%template(MyVectorPtr) std::vector<int &>;
,我会收到很长的回溯:
In file included from C:/ProgramData/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/x86_64-w64-mingw32/bit+allocator.h:33,
from C:/ProgramData/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/allocator.h:46,
from C:/ProgramData/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/string:41,
from C:/ProgramData/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/stdexcept:39,
from dft_wrap.cxx:2743:
C:/ProgramData/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/lib/gcc/x4-w64-mingw32/8.1.0/include/c++/ext/new_allocator.h: In instantiation of 'cl__gnu_cxx::new_allocator<int&>':
C:/ProgramData/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/lib/gcc/x4-w64-mingw32/8.1.0/include/c++/bits/allocator.h:108:11: required from 'clstd::allocator<int&>'
C:/ProgramData/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/lib/gcc/x4-w64-mingw32/8.1.0/include/c++/bits/stl_vector.h:84:21: required from 'st std::_Vector_base<int&, std::allocator<int&> >'
C:/ProgramData/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/lib/gcc/x4-w64-mingw32/8.1.0/include/c++/bits/stl_vector.h:339:11: required from 'c std::vector<int&, std::allocator<int&> >'
dft_wrap.cxx:4748:45: required from here
C:/ProgramData/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/lib/gcc/x4-w64-mingw32/8.1.0/include/c++/ext/new_allocator.h:63:26: error: forming por to reference type 'int&'
typedef _Tp* pointer;
^~~~~~~
C:/ProgramData/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/lib/gcc/x4-w64-mingw32/8.1.0/include/c++/ext/new_allocator.h:64:26: error: forming por to reference type 'int&'
typedef const _Tp* const_pointer;
^~~~~~~~~~~~~
In file included from C:/ProgramData/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/string:41,
from C:/ProgramData/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/stdexcept:39,
from dft_wrap.cxx:2743:
C:/ProgramData/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/lib/gcc/x4-w64-mingw32/8.1.0/include/c++/bits/allocator.h: In instantiation of 'class::allocator<int&>':
C:/ProgramData/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/lib/gcc/x4-w64-mingw32/8.1.0/include/c++/bits/stl_vector.h:84:21: required from 'st std::_Vector_base<int&, std::allocator<int&> >'
C:/ProgramData/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/lib/gcc/x4-w64-mingw32/8.1.0/include/c++/bits/stl_vector.h:339:11: required from 'c std::vector<int&, std::allocator<int&> >'
dft_wrap.cxx:4748:45: required from here
C:/ProgramData/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/lib/gcc/x4-w64-mingw32/8.1.0/include/c++/bits/allocator.h:113:26: error: forming pointo reference type 'int&'
typedef _Tp* pointer;
^~~~~~~
C:/ProgramData/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/lib/gcc/x4-w64-mingw32/8.1.0/include/c++/bits/allocator.h:114:26: error: forming pointo reference type 'int&'
typedef const _Tp* const_pointer;
^~~~~~~~~~~~~
In file included from C:/ProgramData/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/ext/alloc_traits.h:36,
from C:/ProgramData/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/basic_string.h:40
from C:/ProgramData/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/string:52,
from C:/ProgramData/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/stdexcept:39,
from dft_wrap.cxx:2743:
打包的文件创建没有问题,它也编译了,现在尝试在 python;
中使用它
PS C:\Users\me\graphy\graphy> python
Python 3.7.6(默认,2020 年 1 月 8 日,20:23:39)[MSC v.1916 64 位 (AMD64)] :: Anaconda, Inc. on win32
Warning:
This Python interpreter is in a conda environment, but the environment has
not been activated. Libraries may fail to load. To activate this environment
please see https://conda.io/activation
Type "help", "copyright", "credits" or "license" for more information.
>>> from cpp_code import *
>>> worker([5])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Users\me\graphy\graphy\cpp_code.py", line 233, in cpp_code
return _cpp_code.worker(v)
TypeError: in method 'cpp_code', argument 1 of type 'vector< int > &'
>>>
如何 'cast' 引用 python 列表,我已经检查了文档和大量 Whosebug 但无济于事,欢迎任何帮助。
谢谢。
要修改向量,您必须创建它的一个实例。它不能直接修改您试图传递的 Python 列表。这是一个工作示例:
%module 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);
演示:
>>> import test
>>> v = test.MyVector([1,2,3])
>>> v
<test.MyVector; proxy of <Swig Object of type 'std::vector< int > *' at 0x000001EDE38F87E0> >
>>> list(v) # to view it as a Python object
[1, 2, 3]
>>> test.worker(v)
>>> list(v)
[1, 2, 3, 123]
注意v
是vector的代理,所以可以访问vector
方法:
>>> v.size()
4
>>> v[-1]
123
>>> v.pop()
123
>>> v.push_back(7)
>>> v.size()
4
>>> list(v)
[1, 2, 3, 7]
我一直在尝试使用 swig 包装函数采用向量引用(以启用修改)形式的 C++ 代码:
//cpp_code.cpp
void worker(vector<int> &v){
// do something
}
// cpp_code.i
/* File: cpp_code.i */
%module cpp_code
%include "std_vector.i"
%include "typemaps.i"
%{
#include "cpp_code.cpp"
%}
%template(MyVector) std::vector<int>;
//%template(MyVectorPtr) std::vector<int &>;
%include "cpp_code.cpp"
void worker(vector<int> &v);
如果我取消注释部分 //%template(MyVectorPtr) std::vector<int &>;
,我会收到很长的回溯:
In file included from C:/ProgramData/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/x86_64-w64-mingw32/bit+allocator.h:33,
from C:/ProgramData/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/allocator.h:46,
from C:/ProgramData/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/string:41,
from C:/ProgramData/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/stdexcept:39,
from dft_wrap.cxx:2743:
C:/ProgramData/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/lib/gcc/x4-w64-mingw32/8.1.0/include/c++/ext/new_allocator.h: In instantiation of 'cl__gnu_cxx::new_allocator<int&>':
C:/ProgramData/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/lib/gcc/x4-w64-mingw32/8.1.0/include/c++/bits/allocator.h:108:11: required from 'clstd::allocator<int&>'
C:/ProgramData/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/lib/gcc/x4-w64-mingw32/8.1.0/include/c++/bits/stl_vector.h:84:21: required from 'st std::_Vector_base<int&, std::allocator<int&> >'
C:/ProgramData/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/lib/gcc/x4-w64-mingw32/8.1.0/include/c++/bits/stl_vector.h:339:11: required from 'c std::vector<int&, std::allocator<int&> >'
dft_wrap.cxx:4748:45: required from here
C:/ProgramData/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/lib/gcc/x4-w64-mingw32/8.1.0/include/c++/ext/new_allocator.h:63:26: error: forming por to reference type 'int&'
typedef _Tp* pointer;
^~~~~~~
C:/ProgramData/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/lib/gcc/x4-w64-mingw32/8.1.0/include/c++/ext/new_allocator.h:64:26: error: forming por to reference type 'int&'
typedef const _Tp* const_pointer;
^~~~~~~~~~~~~
In file included from C:/ProgramData/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/string:41,
from C:/ProgramData/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/stdexcept:39,
from dft_wrap.cxx:2743:
C:/ProgramData/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/lib/gcc/x4-w64-mingw32/8.1.0/include/c++/bits/allocator.h: In instantiation of 'class::allocator<int&>':
C:/ProgramData/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/lib/gcc/x4-w64-mingw32/8.1.0/include/c++/bits/stl_vector.h:84:21: required from 'st std::_Vector_base<int&, std::allocator<int&> >'
C:/ProgramData/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/lib/gcc/x4-w64-mingw32/8.1.0/include/c++/bits/stl_vector.h:339:11: required from 'c std::vector<int&, std::allocator<int&> >'
dft_wrap.cxx:4748:45: required from here
C:/ProgramData/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/lib/gcc/x4-w64-mingw32/8.1.0/include/c++/bits/allocator.h:113:26: error: forming pointo reference type 'int&'
typedef _Tp* pointer;
^~~~~~~
C:/ProgramData/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/lib/gcc/x4-w64-mingw32/8.1.0/include/c++/bits/allocator.h:114:26: error: forming pointo reference type 'int&'
typedef const _Tp* const_pointer;
^~~~~~~~~~~~~
In file included from C:/ProgramData/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/ext/alloc_traits.h:36,
from C:/ProgramData/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/basic_string.h:40
from C:/ProgramData/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/string:52,
from C:/ProgramData/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/stdexcept:39,
from dft_wrap.cxx:2743:
打包的文件创建没有问题,它也编译了,现在尝试在 python;
中使用它PS C:\Users\me\graphy\graphy> python Python 3.7.6(默认,2020 年 1 月 8 日,20:23:39)[MSC v.1916 64 位 (AMD64)] :: Anaconda, Inc. on win32
Warning:
This Python interpreter is in a conda environment, but the environment has
not been activated. Libraries may fail to load. To activate this environment
please see https://conda.io/activation
Type "help", "copyright", "credits" or "license" for more information.
>>> from cpp_code import *
>>> worker([5])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Users\me\graphy\graphy\cpp_code.py", line 233, in cpp_code
return _cpp_code.worker(v)
TypeError: in method 'cpp_code', argument 1 of type 'vector< int > &'
>>>
如何 'cast' 引用 python 列表,我已经检查了文档和大量 Whosebug 但无济于事,欢迎任何帮助。
谢谢。
要修改向量,您必须创建它的一个实例。它不能直接修改您试图传递的 Python 列表。这是一个工作示例:
%module 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);
演示:
>>> import test
>>> v = test.MyVector([1,2,3])
>>> v
<test.MyVector; proxy of <Swig Object of type 'std::vector< int > *' at 0x000001EDE38F87E0> >
>>> list(v) # to view it as a Python object
[1, 2, 3]
>>> test.worker(v)
>>> list(v)
[1, 2, 3, 123]
注意v
是vector的代理,所以可以访问vector
方法:
>>> v.size()
4
>>> v[-1]
123
>>> v.pop()
123
>>> v.push_back(7)
>>> v.size()
4
>>> list(v)
[1, 2, 3, 7]