2

我正在尝试包装一个使用 auto_ptr 的 C++ 库。我正在使用 swig 并想生成 python 绑定。我在这里看到了 swig 文档中关于如何使用 swig 和智能指针的部分。但我无法让它工作。

Swig 生成想要使用 const 引用初始化 auto_ptr 的代码,但 auto_ptr 使用非常量引用定义了复制构造函数,例如 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})
4

2 回答 2

1

我不相信您能够成功地将这段代码包装在 SWIG 中。问题是 auto_ptr 在复制时会更改所有权。这就是为什么它要求复制构造函数没有 const。SWIG 在内部管理对象所有权的方式意味着,如果没有大量自定义 SWIG 代码,您不太可能获得所需的所有权行为。

于 2011-03-11T14:31:38.403 回答
1

我发现提示如何在 libRETS 中执行此操作,您需要基于每个方法执行此操作:

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

基本上你想解开你从 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));
于 2011-09-07T17:50:37.393 回答