我正在尝试包装一个使用auto_ptr的C ++库。我正在使用swig 并希望生成python绑定。我看过swig文档中有关如何使用swig和智能指针here的部分。但我无法让它发挥作用。
Swig生成想要使用const初始化auto_ptr的代码 引用,但auto_ptr使用非const定义复制构造函数 参考例如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 :(得分:1)
我不相信您能够在SWIG中成功包装此代码。问题是auto_ptr在复制时会更改所有权。这就是为什么它要求复制构造函数不具有const。 SWIG在内部管理对象所有权的方式意味着如果没有大量自定义SWIG代码,您不太可能获得所需的所有权行为。
答案 1 :(得分: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));