2015-04-17 6 views
15

Sto tentando di utilizzare SWIG per avvolgere (in C#) un codice C++ che contiene una classe template che include uno std::vector<T>. Ho visto vari riferimenti su internet su come dichiarare i modelli per i tipi di vettori, ma non riesco a farlo funzionare con il livello aggiuntivo di astrazione. Questo è quello che sto facendo nel file interface.i ad esempio:Come ottenere SWIG per applicare i modelli quando si esegue il wrapping di una classe template contenente vettori?

// interface.i file  
%module myNamespaceWrapper 
%{ 
#include "myVector.h" 
%} 

%include "myVector.h" 
%include "std_string.i" 
%include "std_vector.i" 

namespace std { 
%template(vector_MyType) vector<MyType*>; 
%template(vector_Int) vector<int>; 
} 

namespace myNamespace { 
%template(myVectorMyType) myVector<MyType*>; 
%template(myVectorInt) myVector<int>; 
} 

Anche se questo sembra creare i tipi C# corrispondenti correttamente da soli, i modelli std :: vector che ho cercato di definire non vengono applicate ad altre classi che li usano internamente, inclusi tramite file header. Per mostrare che cosa voglio dire, c'è un C++ classe come:

// myVector.h 
namespace myNamespace 
{  
    template<class T> 
    class myVector 
    { 

    private : 
     std::vector<T> vect; 

    public : 
     myVector(){} 
     virtual ~myVector(){} 

     virtual const std::vector<T> & getVect() 
     { 
      return vect; 
     } 

     virtual T& front() 
     { 
      return vect.front(); 
     } 
    } 
} 

Anche se ho una classe vector_MyType creato da SWIG, quando si avvolge la mia classe template non sta usando e invece dando un sacco di esempi come questo :

public class myVectorMyType : global::System.IDisposable { 

    public virtual SWIGTYPE_p_p_myNamespace__MyType front() { 
     SWIGTYPE_p_p_myNamespace__MyType ret = new SWIGTYPE_p_p_myNamespace__MyType(myNamespaceWrapperPINVOKE.myVectorMyType_front__SWIG_0(swigCPtr), false); 
     return ret; 
    } 

    public virtual SWIGTYPE_p_myNamespace__std__vectorT_myNamespace__MyType_p_t getVect() { 
     SWIGTYPE_p_myNamespace__std__vectorT_myNamespace__MyType_p_t ret = new SWIGTYPE_p_myNamespace__std__vectorT_myNamespace__MyType_p_t(myNamespaceWrapperPINVOKE.myVectorMyType_getVect(swigCPtr), false); 
     return ret; 
    } 
} 

favore qualcuno può consigliare ciò che mi manca per SWIG per generare il wrapper utilizzando MyType e vector_MyType invece di SWIGTYPE_p_myNamespace__std__vectorT_myNamespace__MyType_p_t e SWIGTYPE_p_p_myNamespace__MyType?

È questo qualcosa a che fare con la funzione getVect() modello ritorno T&, cioè avrei bisogno di fare nulla di diverso per il caso %template(myVectorInt) myVector<int>;, dove int non è un puntatore?

+2

Quale versione di SWIG stai usando? Ho provato il tuo esempio con 2.0.11 e 3.0.5 e le fonti C# dove sono state generate correttamente, ad esempio: 'public virtual vector_MyType getVect() { vector_MyType ret = new vector_MyType (myNamespaceWrapperPINVOKE.myVectorMyType_getVect (swigCPtr), false); return ret; } –

+0

Grazie per aver provato questo! Sto anche usando 3.0.5. Dal momento che hai funzionato, sono stato in grado di trovare il problema con il mio codice. Non era esattamente come ho messo la domanda, in realtà ho avuto un '' using namespace std; 'nella sezione' namespace myNamespace {} 'che stava causando il problema. Rimuovendo questo, funziona come previsto. – SWilliams

+0

Cerca di correggere l'esempio nella domanda e scrivilo come risposta? – Flexo

risposta

0

Alla fine ho realizzato il mio errore e SWIG generato le classi come previsto.

// interface.i file  
%module myNamespaceWrapper 
%{ 
#include "myVector.h" 
%} 

%include "myVector.h" 
%include "std_string.i" 
%include "std_vector.i" 

namespace std { 
%template(vector_MyType) vector<MyType*>; 
%template(vector_Int) vector<int>; 
} 

namespace myNamespace { 
// using namespace std; // don't include this! 
%template(myVectorMyType) myVector<MyType*>; 
%template(myVectorInt) myVector<int>; 
} 

Questo prodotto classi come:

public class myVectorMyType : global::System.IDisposable { 
    private global::System.Runtime.InteropServices.HandleRef swigCPtr; 
    protected bool swigCMemOwn; 

    ... 

    public virtual vector_MyType getVect() { 
    vector_MyType ret = new vector_MyType(myNamespaceWrapperPINVOKE.myVectorMyType_getVect(swigCPtr), false); 
    return ret; 
    } 
} 

in cui il sottostante vector_MyType è secondo il modello std_vector.i:

public class vector_MyType: global::System.IDisposable, global::System.Collections.IEnumerable 
    , global::System.Collections.Generic.IList<MyType> 
{...} 
0

vorrei raccomandare di evitare l'emissione e basta creare wrapper per ogni esemplificazione è necessario:

class wrap_int : public temp <int> 
{ 
}; 
Problemi correlati