如何在没有 -builtin
的情况下告诉编译的模块,使用 %import
编译了-builtin
ed模块?当非内置模块假定来自第一个模块的对象具有包装器时,天真地这样做会给我带来段错误。
(如果所有内容都是在-builtin
已关闭关闭的情况下进行编译,或者单独使用第二个模块且-builtin
已启用时,我绝不会遇到段错误;只是在将它们一起使用时使用不同的编译选项。)
我有几个单独的模块,我使用SWIG。假设其中一个名为A
,并包含基本对象(四元数)。因为它包含许多计算中涉及的基本对象,所以我更喜欢使用SWIG的-builtin
选项。我测试了它,这确实在时间上产生了非常显着的差异。
现在,我还有另一个名为B
的模块需要使用A
中的对象。但是B
包含很多胖的复合对象,我很多次都不会这样做,所以我不认为在这里使用-builtin
有很多好处。此外,我真的想扩展B
中的类,并执行-builtin
无法实现的各种事情。
问题是我必须在%import A.i
内B.i
。但是,为B
生成的代码假定A
对象具有额外的包装器,而不是使用-builtin
。因此,当我使用B
时,我会遇到段错误。
(至少,我假设segfaults结果是因为B
假设额外的包装器。我查看了我的B_wrap.cpp
文件足以看到它假设存在这些包装器,尽管我可以'我真的说我做了任何测试,以确保问题来自哪里。但是,段错误只与A
B
的使用相吻合。A
从来没有给我带来任何麻烦。另外,如果我在没有A
的情况下编译B
和-builtin
,我就永远不会遇到段错误。)
原则上,我可以使用MONK's approach并将我需要添加方法的任何类子类化,同时使用-builtin
编译所有内容。但这会破坏我的C ++代码中的名称和我的python代码中的名称之间的良好对应关系,以及要求一组或另一组用户更改他们使用的名称,以及在对接中一般的痛苦。
我为没有MWE而道歉,但我认为这将是一个不合理的大型MWE。
答案 0 :(得分:1)
我不知道用单独的标志编译是可能的,但我对MONK的解决方案感到满意。结合SWIG的%rename
功能,MONK的方法不需要重命名用户可见的任何内容。此外,它易于实现,每个类我只想修改五行。因此,所有内容都将使用-builtin
进行编译,并且不会出现段错误。虽然这在技术上没有回答我在顶部提出的问题,但它适合我。
所以,我们假设B
中的关键对象是一个名为Classy
的类。我只是告诉SWIG将其重命名为_Classy
(下划线,这样我每次在ipython中使用tab完成时都不必查看它)。然后,我将创建一个子类,这些子类是那些对象的子类。最后,我将创建一个名为Classy
的新对象,它只包含元类。所以我的python用户和我的C ++用户会将它看作同一个对象,但python用户将能够将其子类化。
这是这部分的MWE。一个简单的标题:
// Classy.hpp
class Classy {
public:
Classy() { }
};
和SWIG文件
// test.i
%module "test"
%{
#include "Classy.hpp"
%}
%rename(_Classy) Classy;
%include "Classy.hpp"
%insert("python") %{
class _MetaClassy(type(_Classy)):
pass
class Classy(_Classy):
__metaclass__ = _MetaClassy
Classy.myattr = 'anything'
%}
(看看我们最后在那里添加了一个属性。)最后,设置文件:
# setup.py
from distutils.core import setup, Extension
example_module = Extension('_test',
sources=['test_wrap.cxx'])
setup (name = 'test',
ext_modules = [example_module],
py_modules = ["test"])
现在,只需使用
进行编译和测试swig -python -builtin -c++ test.i
python setup.py build_ext --inplace
python -c 'import test; x=test.Classy(); print x.myattr'
在最后一行中,类型为x
的python对象Classy
确实具有一个属性 - 即使C ++类根本没有任何内容。所以我们成功了。
据推测,这个子类化会使-builtin
对象的Classy
的速度优势失效,但我已经决定我不关心那一个类。另一方面,我可以保留任何我没有显式子类化的对象的速度优势,因此仍然有理由使用builtin
。