2017-01-30 12 views
0

У меня есть массив шаблонов, который я обертываю swig для использования с Python. Я создаю два экземпляра шаблона. Первый код обертки является правильным, но я получаю ошибку компиляции во втором из-за отсутствия идентификатора пространства имен в сгенерированном коде (см. Copy_from 'ниже).SWIG сгенерированный вывод отсутствующего квалификатора пространства имен

Я не знаю, запутывается ли SWIG на двух пространствах имен api & sim, или мне не хватает какого-либо другого классификатора в моих объявлениях. Примечание «copy_from()» ниже - это всего лишь один пример; такая же ошибка возникает и в других функциях оболочки api :: array. Файл интерфейса SWIG (.i), который я строю с , включает и обертывает все типы, показанные ниже.

UPDATE: Я рассмотрел мой .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 

UPDATE 2: Я добавил шаблон псевдоним (см. UPDATE 2: добавленный псевдоним в коде): шаблон с использованием array = api :: array; и SWIG теперь добавляет пространство имен sim, например. sim :: массив < mat3d>. Ошибка компиляции теперь, так как alias 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> 
    ... 
} 
+0

Проблемы с шаблоном обычно являются проблемами с порядком деклараций в файле .i, который вы не указали. –

ответ

0

Это, кажется, решена путем перемещения директивы% шаблона вне блока сим пространства имен к глобальному:

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

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

... который теперь генерирует правильное пространство имен (апи: :)

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 не идентифицировал аргумент функции члена правильно здесь:

template < typename T > class array 
    { 
     copy_from(const array<T>& src); // arg. 'src' is same type as template class (api::array) 
    } 

Возможно, я не понимаю, как SWIG интерпретирует шаблон%, если он помещается в пространство имен. В любом случае, я предполагаю, что эта проблема решена на данный момент.