2010-10-11 4 views
2

J'essaye d'encapsuler une bibliothèque C++ qui utilise auto_ptr. J'utilise swig et je veux générer des liaisons python. J'ai vu la section du document swig sur comment utiliser swig avec des pointeurs intelligents here. Mais je ne peux pas le faire fonctionner. Swig génère un code qui veut initialiser auto_ptr en utilisant une référence const , mais auto_ptr définit le constructeur de copie avec une référence non-const par ex. auto_ptr (auto_ptr &). Le code généré ne compile pas avec "éliminations const qualificateurs". Quand je supprime manuellement le qualificateur const, le code se compile bien.auto_ptr avec swig

J'ai vu beaucoup d'entrées de liste de diffusion mais rien n'a aidé. Quelqu'un peut-il me fournir un exemple de travail. Mon échantillon non de travail est ici:

%module auto_ptr_test 
%{ 
#include <memory> 
#include <iostream> 
using namespace std; 
%} 
namespace std { 
template <class T> 
class auto_ptr { 
    auto_ptr(); 
    auto_ptr(auto_ptr &); 
    T *operator->() const; 
}; 
} 

%inline %{ 
class Test { 
Test() { 
    cout << "Test()" << endl; 
} 
public: 
static std::auto_ptr<Test> create() const { 
    return auto_ptr<Test>(new Test()); 
} 
void greet() { 
    cout << "hello" << endl; 
} 
}; 
%} 

%template() std::auto_ptr<Test>; 

Je l'ai compilé en utilisant CMake avec le CMakeLists.txt suivant:

cmake_minimum_required(VERSION 2.8) 
find_package(SWIG REQUIRED) 
include(${SWIG_USE_FILE}) 

FIND_PACKAGE(PythonLibs) 
INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_PATH}) 

INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) 

SET(CMAKE_SWIG_FLAGS "") 

SET_SOURCE_FILES_PROPERTIES(auto_ptr_test.i PROPERTIES CPLUSPLUS ON) 
SWIG_ADD_MODULE(auto_ptr_test python auto_ptr_test.i) 
SWIG_LINK_LIBRARIES(auto_ptr_test ${PYTHON_LIBRARIES}) 

Répondre

0

Je ne crois pas que vous allez être en mesure de conclure avec succès ce code dans SWIG . Le problème est que auto_ptr change de propriétaire lors de la copie. C'est pourquoi il faut que le constructeur de copie n'ait pas const. La façon dont SWIG gère la propriété des objets en interne signifie qu'il est peu probable que vous obteniez le comportement de propriété souhaité sans beaucoup de code SWIG personnalisé.

1

Je trouve indice comment faire en libRETS, et vous devez le faire sur une base par méthode:

http://code.crt.realtors.org/projects/librets/browser/librets/trunk/project/swig/auto_ptr_release.i?rev=HEAD

Fondamentalement, vous voulez déballer auto_ptr que vous recevez de C++ et l'envelopper avant de passer en C++. Exemple de code à mettre dans le fichier .i est:

//original prototype: 
    //virtual void SetSomething(std::auto_ptr<ValueClass> value) = 0; 
    //replacement to be generated by SWIG: 
    %extend{ 
     void SetSomething(ValueClass *value){ 
      std::auto_ptr<ValueClass> tmp(value); 
      $self->SetSomething(tmp); 
     } 
    } 


    //retrieving object wrapped in auto_ptr using swig macro: 
    %define SWIG_RELEASE_AUTO_PTR(RETURN_TYPE, METHOD_NAME, PROTO, ARGS) 
    %extend { 
    RETURN_TYPE * METHOD_NAME PROTO { 
     std::auto_ptr<RETURN_TYPE> auto_result = self->METHOD_NAME ARGS; 
     return auto_result.release(); 
    } 
    } 
    %enddef 
    // and then inside class: 
    // virtual auto_ptr<ValueClass> SomeMethod(const string& foo) = 0; 
    // replaced with: 
    SWIG_RELEASE_AUTO_PTR(ValueClass,SomeMethod,(const string& foo),(foo));