SWIG生成的输出缺少命名空间限定符

时间:2017-01-30 16:14:51

标签: compiler-errors namespaces swig

我有一个模板数组,我用swig包装以便与Python一起使用。我创建了两个模板实例。第一个包装器的代码是正确的,但是由于生成的代码中缺少名称空间限定符,我在第二个上遇到编译错误(请参阅下面的copy_from)。

我不知道SWIG是否对这两个命名空间api& sim,或者我是否在我的声明中遗漏了其他一些限定词。注意下面的'copy_from()'只是一个例子;在其他api :: array包装器函数中发生相同的错误。我正在构建的SWIG接口(.i)文件 包括并包装下面显示的所有类型。

更新:我查看了我的.i文件,以确保所有包装类型的%包含在以C ++编译时遇到的相同顺序中,即:

%include "mat3d.h"
%include "XMVECTOR.h"
%include "api_array.h" // api::array template decl.
%include "api_array_types.h" // array<XMVECTOR> instantiation 
%include "array_types.h" // api::array<mat3d> instantiation

更新2:我添加了模板别名(请参阅更新2:在代码中添加了别名):     模板使用array = api :: array; 和SWIG现在添加了sim名称空间,例如SIM ::阵列&LT; mat3d&gt;。现在没有编译错误,因为别名sim :: array映射到api :: array - 但仍然不明白为什么。不喜欢它生成两个不同的名称空间引用相同的模板类...

namespace api { 
    template < typename T > class array : public wrapped<array<typename array_internal_type<T> >, typename array_internal_type<T> >
    {
        ...
        int         copy_from( const array<T>& src ); // member generating an error 

    };
}

class XMVECTOR {...} declared in global namespace

namespace api {
    extern template class array<XMVECTOR>;
    %template(xyzV) array<XMVECTOR>;
}

class mat3d { ... } // declared in global namespace

namespace sim {
    template <typename T> using array = api::array<T>; // UPDATE 2: added template alias
    extern template class api::array<mat3d>;
    %template(matrixV) api::array<mat3d>;
}

// sample SWIG-generated code... this wrapper compiles and executes correctly
SWIGINTERN PyObject *_wrap_xyzV_copy_from( PyObject *SWIGUNUSEDPARM( self ), PyObject *args ) {
    PyObject *resultobj = 0;
    api::array< XMVECTOR > *arg1 = (api::array< XMVECTOR > *) 0;
    api::array< XMVECTOR > *arg2 = 0;
    ...
}


// this wrapper fails to compile
SWIGINTERN PyObject *_wrap_matrixV_copy_from( PyObject *SWIGUNUSEDPARM( self ), PyObject *args ) {
    PyObject *resultobj = 0;
    api::array< mat3d > *arg1 = (api::array_copy_from mat3d > *) 0;
    array< mat3d > *arg2 = 0; // error: no namespace on array; should be api::array. Applying update #2, this is "fixed" as sim::array< mat3d > 
    ...
}

1 个答案:

答案 0 :(得分:0)

这似乎可以通过将sim命名空间块之外的%template指令移动到global:

来解决
select
    max(id),
    contributor_id,
    project_id,
    sum(assigned_ppoints * (state = 2)::integer)
from t
group by 2,3

...现在生成正确的命名空间(api ::)

        // old: 
        namespace sim { ... 
            %template(matrixV) api::array<mat3d>;
        }   

        // new:
        namespace sim { ... }
        %template(matrixV) api::array<mat3d>;

不确定为什么SWIG没有在这里正确识别成员函数参数:

 SWIGINTERN PyObject *_wrap_matrixV_copy_from(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
    PyObject *resultobj = 0;
    api::array< mat3d > *arg1 = (api::array< mat3d > *) 0 ;
    api::array< mat3d > *arg2 = 0 ; // correct api:: namespace added

如果碰巧将%模板置于命名空间内,我可能会误解SWIG如何解释该模板。无论如何,我现在认为这个问题已经解决了。