2010-10-11 33 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));