给定这组文件:
食品卫生:
#pragma once
#include <stdio.h>
template <class T0> class Foo {
public:
T0 m[3];
Foo(const T0 &a, const T0 &b, const T0 &c) {
m[0] = a;
m[1] = b;
m[2] = c;
}
void info() { printf("%d %d %d\n", m[0], m[1], m[2]); }
// T0 &operator[](int id) { return ((T0 *)m)[id]; }
};
在食品.cpp公司名称:
^{pr2}$foo.i(尝试1):
%module foo
%{
#include "foo.h"
%}
%include "foo.h"
%template(intFoo) Foo<int>;
%extend Foo{
T0& __getitem__(int id) { return ((T0 *)m)[id]; }
}
在设置.py公司名称:
import os
import sys
from setuptools import setup, Extension
foo_module = Extension('_foo',
sources=[
'foo.i',
'foo.cpp'
],
swig_opts=['-c++', '-py3', '-builtin'],
include_dirs=['.']
)
setup(name='foo',
version='0.1',
platforms=['Windows', 'Linux'],
ext_modules=[foo_module],
py_modules=["foo"],
)
在测试.py公司名称:
from foo import intFoo
a = intFoo(10,20,30)
print(dir(a))
a.info()
print(a[2])
我构建扩展运行:
python setup.py build_ext --force -i
但当我想逃跑的时候测试.py我会得到:
TypeError: 'foo.intFoo' object does not support indexing
foo.i
中的extend
语句是在任何其他相关线程上建议的答案,这意味着我在这里使用它不正确。有人能解释一下如何解决这个问题,这样当我运行test.py
时,就可以成功地使用[]
运算符了吗?
另一次尝试:
尝试2:
%module foo
%{
#include "foo.h"
%}
%include "foo.h"
%template(intFoo) Foo<int>;
%extend intFoo{
T0& __getitem__(int id) { return ((T0 *)m)[id]; }
}
引发此错误TypeError: 'foo.intFoo' object does not support indexing
尝试3
%module foo
%{
#include "foo.h"
%}
%include "foo.h"
%extend Foo{
T0& __getitem__(int id) { return ((T0 *)m)[id]; }
}
%template(intFoo) Foo<int>;
引发此错误foo_wrap.cpp(3808): error C2065: 'm': undeclared identifier
(在这个例子中,我使用的是foo.I的第一个版本)
首先,需要在
%template
指令之前指定%extend
才能产生任何效果。在修复后,我们现在从
%extend
代码中得到一个编译器错误:之所以会发生这种情况,是因为使用} 为我们提供适当的变量。(有必要快速浏览一下生成的代码,以了解其工作原理)
%extend
添加的方法实际上并不是要添加它们的类的成员。要在这个上下文中访问m
,我们需要用$self->m
来引用它。SWIG将replace ^{在调试类型映射或扩展时,一个有用的提示是搜索您在SWIG生成的输出中编写的代码—如果没有,那么它就不会按照您的想法应用。在
因此,一旦我们修复了
^{pr2}$m
未声明的错误,我们将遇到另一个问题,因为您使用-builtin
进行了编译:即使您添加了
__getitem__
,但是使用f[n]
建立索引仍然不起作用。这是因为在Python中使用纯C-API类时,操作符重载的工作方式并不相同。您已经成功地添加了一个__getitem__
方法,但是Python正在builtin type's slots(特别是mp_下标)中寻找执行该操作的方法。所以我们也需要解决这个问题。完成后,我看起来像:现在我们可以做你想做的:
(实际上,您不必再调用它
__getitem__
,因为该函数是在插槽中注册的,因此应该可以不使用%extend
来调用operator[]
)最后,您可能希望将返回类型改为
const T0&
,或者更好地为非常数整型引用编写一个Python类型到代理对象。在我已经将错误的答案(声明
%extent
只能在没有-builtin
选项的情况下使用)改为有效的方法,但同样是没有“内置”选项在设置.py在
福。我
^{pr2}$请注意,扩展是如何生成
Python
代码的,它允许您做许多复杂的事情。在老答案:
根据SWIG文档,python层被剥离,因此
%extend
特性被忽略(这是不正确的,不会创建代理对象)见http://www.swig.org/Doc3.0/SWIGDocumentation.html
相关问题 更多 >
编程相关推荐