繁体   English   中英

Swig shared_ptr宏与模板类和派生类

[英]Swig shared_ptr macro with templated class and derived classes

这个问题在某种程度上是这里发布的问题的扩展: 具有模板类的SWIG_SHARED_PTR宏虽然问题可能完全不相关。

基本设置是这样的:我试图让SWIG将模板化的类包装为shared_ptr。 所以接口文件看起来应该是这样的

%shared_ptr(template_instance)
%include template_class.cpp
%template(vector_instance) template_class<int>;

现在的问题是template_class有很多派生类,这会在swig中引发很多警告,然后构建错误。 这些类不需要作为shared_ptr处理,所以我宁愿忽略上面代码生成的警告。 错误的解决方案似乎是:

%shared_ptr(template_derived1)
%shared_ptr(template_derived2)
.
.
.
%shared_ptr(template_derivedn)
%shared_ptr(template_instance)
%include template_class.cpp
%template(vector_instance) template_class<int>;

这是有效的,但是是一个巨大的混乱,并且我认为将所有内容表示为shared_ptr(它是什么?)必然存在一些缺点。 这附近有人吗?

编辑:更新具体示例

test.h

class Base
{
  int base_member;
};

class Derived : public Base
{
  int derived_member;
};

test.i

%module test
%{
#include "test.h"
#include <boost/shared_ptr.hpp>
  %}

%include <boost_shared_ptr.i>
%shared_ptr(Base)
%include test.h

命令:

swig -python -c++ test.i 
g++ -fPIC -I /usr/include/python2.7 -c test_wrap.cxx

在这个精简的示例中,swig调用会发出警告,而g ++调用会产生错误。 请注意,我删除了模板,因为它似乎不是问题的一个组成部分。

通过注释解决错误

%shared_ptr(Base)

swig生成的警告是:

test.h:10: Warning 520: Derived class 'Derived' of 'Base' is not similarly marked as a smart pointer

而g ++的错误是:

test_wrap.cxx: In function ‘PyObject* _wrap_delete_Derived(PyObject*, PyObject*)’:
test_wrap.cxx:3155:22: error: ‘smartarg1’ was not declared in this scope

这里的警告是因为你需要告诉SWIG关于整个类层次结构,而不仅仅是基类,以便能够有效地使用智能指针。 它需要能够在智能指针之间进行转换,以便任何采用指向Base的智能指针的东西也可以接受一个到Derived 所以你的界面文件需要是:

%module test
%{
#include "test.h"
#include <boost/shared_ptr.hpp>
%}

%include <boost_shared_ptr.i>
%shared_ptr(Base)
%shared_ptr(Derived)
%include "test.h"

这解决了被警告的问题并生成了在我的机器上编译好的代码。

如果您不想告诉SWIG所有派生类型,最简单的方法是从SWIG中完全隐藏类型 - 只从您想要包装的东西中公开Base类型。 您可以通过几种方式实现这一点,最不具侵入性的是将接口文件更改为:

%module test
%{
#include "test.h"
#include <boost/shared_ptr.hpp>
%}

%include <boost_shared_ptr.i>
%ignore Derived;
%shared_ptr(Base)
%include "test.h"

这会导致只包装Base ,因此无法生成无法编译的代码。

或者,因为每个类型仍需要%ignore ,您可以修改头文件以完全隐藏Derived自SWIG的声明/定义:

class Base
{
  int base_member;
};
#ifndef SWIG
class Derived : public Base
{
  int derived_member;
};
#endif

如果你的项目被组织起来,每个类型(粗略地)有一个头文件,你可以通过简单地不使用%include和基本文件以外的文件来更简单地执行此操作。

如果你仍然想要包装它们,但不是作为smart_ptr,我认为你将不得不接受将会有很多%smart_ptr - 你可以自动生成它们吗? 您可能可以使用模块玩游戏,但我认为这不会轻松或值得付出努力。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM