使用swig的auto_ptr
我正在尝试将一个使用了auto_ptr的C++库进行封装。我使用的是swig,想要生成Python的绑定代码。我看过swig文档中关于如何使用智能指针的部分,具体可以在这里找到。但是我一直没能成功。
Swig生成的代码试图用一个常量引用来初始化auto_ptr,但auto_ptr的复制构造函数是用一个非常量引用定义的,比如说auto_ptr(auto_ptr &)。生成的代码在编译时出现了“丢弃常量限定符”的错误。当我手动删除常量限定符后,代码就能正常编译了。
我在很多邮件列表中找过相关信息,但都没有帮助。有没有人能给我一个可以正常工作的例子?我的不工作示例在这里:
%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})
2 个回答
1
我在libRETS中找到了如何实现的提示,你需要针对每个方法单独处理:
基本上,你需要把从C++接收到的auto_ptr解包,然后在传递给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));
1
我觉得你可能无法顺利地把这段代码用SWIG封装起来。问题在于,auto_ptr在复制的时候会改变所有权。这就是为什么它的复制构造函数不能加const的原因。SWIG内部管理对象所有权的方式意味着,如果没有很多自定义的SWIG代码,你很难实现想要的所有权行为。