【问题标题】:wrapping c++ vector reference with swig用 swig 包装 c++ 矢量引用
【发布时间】:2021-07-13 20:18:29
【问题描述】:

我一直在尝试使用 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&lt;int &amp;&gt;;,我会收到很长的回溯:

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

如何“转换”对 python 列表的引用,我已经检查了文档和大量 stackOverflow 但无济于事,欢迎任何帮助。

谢谢。

【问题讨论】:

    标签: python c++ swig


    【解决方案1】:

    要修改向量,您必须创建它的实例。它不能直接修改您尝试传递的 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方法:

    >>> v.size()
    4
    >>> v[-1]
    123
    >>> v.pop()
    123
    >>> v.push_back(7)
    >>> v.size()
    4
    >>> list(v)
    [1, 2, 3, 7]
    

    【讨论】:

    • 非常感谢,当我尝试将您的解决方案扩展到二维向量时。它抛出了一个错误''vector> &',请我在这方面需要帮助,在尝试之前我添加了另一个模板来处理二维向量。
    • @Moses 这是一个新问题,但应该只需要另一个模板实例化。 %template(MyVector2d) std::vector&lt;std::vector&lt;int&gt;&gt;;
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-10
    • 2021-08-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多