在 Python、C++0x 和 SWIG 2.0 中,构建如下 C++ 代码时遇到问题:
#include <string>
#include <iostream>
#include <memory>
using namespace std;
struct Base {
virtual string name();
int foo;
shared_ptr<Base> mine;
Base(int);
virtual ~Base() {}
virtual void doit(shared_ptr<Base> b) {
cout << name() << " doing it to " << b->name() << endl;
mine = b;
}
virtual shared_ptr<Base> getit() {
return mine;
}
};
struct Derived : Base {
virtual string name();
int bar;
Derived(int, int);
};
对应的接口文件如下:
%module(directors="1") foo
%feature("director");
%include <std_string.i>
%include <std_shared_ptr.i>
%shared_ptr(Base)
%shared_ptr(Derived)
%{
#define SWIG_FILE_WITH_INIT
#include "foo.hpp"
%}
%include "foo.hpp"
在 Python 会话中,执行如下操作:
>>> import foo
>>> b = foo.Base(42)
>>> d = foo.Derived(23,64)
>>> b.doit(d)
Base doing it to Derived
>>> g = b.getit()
>>> g
<foo.Base; proxy of <Swig Object of type 'std::shared_ptr< Base > *' at 0x7f7bd1391930> >
>>> d
<foo.Derived; proxy of <Swig Object of type 'std::shared_ptr< Derived > *' at 0x7f7bd137ce10> >
>>> d == g
False
>>> d is g
False
>>> d.foo == g.foo
True
>>> d.bar
64
>>> g.bar
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Base' object has no attribute 'bar'
问题在于,无法从 C++ 容器类中获取最派生的代理对象。不知道是否需要为每个基类生成一个函数来执行动态指针转换,如果是,那么用 Python 实现的 Director 子类又该如何处理?
SWIG 似乎无法解决此问题,但 SIP4 可以。SIP4 提供了更好的方式来处理共享指针的包装器。
可以使用 SIP4 的 Makefile 生成器或 distutils 扩展构建系统来构建示例项目,而无需首先生成和安装共享库或手动编辑生成的 Makefile。
以下是使用 SIP4 构建示例项目的具体步骤:
1. 安装 SIP4
pip install sip
2. 创建 SIP 模块文件
[sip]
includedir = /usr/include/python3.9
sipdir = /usr/share/sip/sip
bindingdir = /usr/share/sip/bindings
moduledir = /usr/share/sip/modules
debug = True
3. 创建 C++ 头文件
#include <string>
#include <iostream>
#include <memory>
using namespace std;
class Base {
public:
virtual string name() { return "Base"; }
virtual void print() { cout << "Base" << endl; }
};
class Derived : public Base {
public:
virtual string name() { return "Derived"; }
virtual void print() { cout << "Derived" << endl; }
};
4. 创建 SIP 接口文件
class Base {
string name();
void print();
};
class Derived : Base {
string name();
void print();
};
5. 运行 SIP 生成绑定代码
sip -c sip.cfg -b build -t Qt5 Base.h
6. 编译并安装绑定代码
cd build
make
sudo make install
7. 在 Python 中导入绑定代码
from Base import Base, Derived
b = Base()
d = Derived()
b.print() # 输出 "Base"
d.print() # 输出 "Derived"
通过以上步骤,可以在 Python 中使用 SIP4 来处理共享指针的包装器,并构建示例项目。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。