2013-04-09 7 views
5

Sto usando SWIG con successo per costruire un'interfaccia wrapper per rendere le mie librerie C++ disponibili in C#. Recentemente ho esposto alcuni oggetti boost::optional<> e SWIG sta avendo problemi con loro. C'è un modo standard per affrontare questo? Qualcuno deve averlo imbattuto prima ...Puoi potenziare SWIG :: opzionale <>?

+0

Questa non è una domanda più ampia su come SWIG si occupa di arguzia h modelli? Non ho usato SWIG, ma una scansione veloce suggerisce che potrebbero esserci delle limitazioni nei modelli. – dotcomslashnet

+2

@dotcomslashnet Sì e no. SWIG può essere configurato per personalizzare il modo in cui traduce/avvolge qualsiasi cosa. Speravo che sia SWIG sia 'boost :: optional <>' fossero usati abbastanza ampiamente da qualcuno che lo ha già fatto, quindi non devo re-inventare la ruota. :-) – aldo

risposta

3

Poiché SWIG non capisce i tipi di boost, devono essere scritti i typemaps. Ecco un paio di typemap per boost::optional<int>.

Da Python, None o un numero intero può essere passato in una funzione:

%typemap(in) boost::optional<int> %{ 
    if($input == Py_None) 
     $1 = boost::optional<int>(); 
    else 
     $1 = boost::optional<int>(PyLong_AsLong($input)); 
%} 

Un restituito boost::optional<int> verrà convertito in un Nessuno o un intero Python:

%typemap(out) boost::optional<int> %{ 
    if($1) 
     $result = PyLong_FromLong(*$1); 
    else 
    { 
     $result = Py_None; 
     Py_INCREF(Py_None); 
    } 
%} 
+0

Grazie! Dovrò adattarlo per C# invece di Python, ma questo non dovrebbe essere un problema. – aldo

+0

Oops, hai completamente perso il tuo tag C#, ma dovrebbe essere un piccolo cambiamento. –

0

Una possibile C# soluzione usando std :: vector

#if SWIGCSHARP 

// C++ 
%typemap(ctype) boost::optional<int32_t> "void *" 
%typemap(out) boost::optional<int32_t> %{ 

    std::vector<int32_t> result_vec; 
    if (!!$1) 
    { 
     result_vec = std::vector<int32_t>(1, $1.get()); 
    } 
    else 
    { 
     result_vec = std::vector<int32_t>(); 
    } 

    $result = new std::vector<uint32_t>((const std::vector<uint32_t> &)result_vec); 
%} 

// C# 
%typemap(imtype) boost::optional<int32_t> "global::System.IntPtr" 
%typemap(cstype) boost::optional<int32_t> "int?" 
%typemap(csout, excode=SWIGEXCODE) boost::optional<int32_t> { 
    SWIG_IntVector ret = new SWIG_IntVector($imcall, true);$excode 

    if (ret.Count > 1) { 
     throw new System.Exception("Return vector contains more then one element"); 
    } 
    else if (ret.Count == 1) { 
     return ret[0]; 
    } 
    else { 
     return null; 
    } 
} 

#endif //SWIGCSHARP