2010-10-11 3 views
2

Я пытаюсь обернуть библиотеку C++, которая использует auto_ptr. Я использую swig и хочу сгенерировать привязки python. Я видел раздел документа swig о том, как использовать swig с умными указателями here. Но я не могу заставить его работать.auto_ptr с swig

Swig генерирует код, который хочет инициализировать auto_ptr, используя ссылку const , но auto_ptr определяет конструктор копирования с неконстантным ссылкой, например. auto_ptr (auto_ptr &). Сгенерированный код не компилируется с помощью «discards const qualifiers». Когда я вручную удаляет классификатор const, код компилируется в порядке.

Я видел множество записей списка рассылки, но ничего не помогло. Может кто-нибудь предоставить мне рабочий пример. Мой нерабочем образец здесь:

%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>; 

Я составил его с помощью CMake со следующим CMakeLists.txt:

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}) 

ответ

0

Я не верю, что вы собираетесь быть в состоянии успешно завершить этот код в SWIG , Проблема в том, что auto_ptr изменяет право собственности при копировании. Вот почему для конструктора копирования не требуется const. Способ, которым SWIG управляет владением объектами внутри, означает, что маловероятно, что вы получите желаемое поведение владельца без большого количества настраиваемых SWIG-кодов.

1

Я нашел подсказку, как это сделать в libRETS, и вы должны сделать это на основе каждого метода:

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

В основном вы хотите разворачивать auto_ptr вы получите от C++ и обернуть его перед передачей на C++. Пример кода, который должен быть помещен в .i-файл:

//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));