gpt4 book ai didi

c++ - 带有模板化类和派生类的 Swig shared_ptr 宏

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:55:55 25 4
gpt4 key购买 nike

这个问题在某些方面是这里发布的问题的扩展: SWIG_SHARED_PTR macro with templated class尽管这个问题可能完全不相关。

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

%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 肯定有一些缺点(它是什么?)。周围有人吗?

编辑:更新具体示例

测试.h

class Base
{
int base_member;
};

class Derived : public Base
{
int derived_member;
};

测试.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 的智能指针。所以你的接口(interface)文件需要是:

%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 类型。您可以通过几种方式做到这一点,侵入性最小的是将接口(interface)文件更改为:

%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,您可以修改头文件以完全隐藏来自 SWIG 的 Derived 的声明/定义:

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

如果你的项目被组织成每种类型有一个头文件(大致),你可以通过简单得多的方式来做到这一点,只需不使用 %include 与文件以外的文件基础一。

如果你仍然想包装它们,但不是作为 smart_ptr 我认为你将不得不接受会有很多 %smart_ptr - 你可以自动生成它们虽然也许?你可以用modules玩游戏,但我认为这并不容易,也不值得付出努力。

关于c++ - 带有模板化类和派生类的 Swig shared_ptr 宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11380483/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com