2010-10-11 32 views
2

我想包裝一個使用auto_ptr的C++庫。我正在使用swig 並希望生成python綁定。我看過關於如何在智能指針here上使用swig的swig文件部分。但我無法讓它工作。帶swig的auto_ptr

痛飲生成希望使用一個const 參考初始化auto_ptr的代碼,但auto_ptr的限定具有非const 參考拷貝構造例如auto_ptr(auto_ptr &)。生成的 代碼不會使用「丟棄const限定符」進行編譯。當我手動 刪除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>; 

我用用下面的CMakeLists.txt cmake的編譯它:

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

我不相信你將能夠在痛飲成功換驗證碼。問題是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));