2013-04-09 17 views
5

Użyłem pomyślnie SWIG do zbudowania interfejsu otoki, aby moje biblioteki C++ były dostępne w C#. Ostatnio wyeksponowałem obiekty o wartości boost::optional<>, a SWIG ma z nimi problemy. Czy istnieje standardowy sposób radzenia sobie z tym? Ktoś musiał już na tym poprzestać ...Czy możesz zwiększyć SWIG :: opcjonalne <>?

+0

Czy to nie jest szersze pytanie o to, jak SWIG radzi sobie z dowcipem h szablony? Nie używałem SWIG, ale szybkie skanowanie sugeruje, że mogą istnieć pewne ograniczenia szablonów. – dotcomslashnet

+2

@dotcomslashnet Tak i nie. SWIG można skonfigurować, aby dostosować sposób, w jaki tłumaczy/owija wszystko. Miałem nadzieję, że zarówno SWIG, jak i 'boost :: optional <>' są powszechnie używane, że ktoś już to zrobił, więc nie muszę ponownie wymyślać koła. :-) – aldo

Odpowiedz

3

Ponieważ SWIG nie rozumie typów doładowań, muszą być zapisane mapy typów. Oto para mapowań dla boost::optional<int>.

Z pythonowa None lub całkowita może być przekazywane do funkcji:

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

zwrócony boost::optional<int> zostaną przekształcone do zerem albo liczbą całkowitą Pythonie

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

Dzięki! Będę musiał dostosować go do C# zamiast Pythona, ale to nie powinno stanowić problemu. – aldo

+0

Ups, całkowicie przegapiłeś swój tag C#, ale powinna to być niewielka zmiana. –

0

możliwe rozwiązanie C# używając std :: wektor

#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 
Powiązane problemy