繁体   English   中英

使用和不使用`-builtin`交互SWIG模块

[英]Interacting SWIG modules with and without `-builtin`

如何在没有 -builtin 情况下告诉编译模块, 使用 -builtin编译%import ed模块? 当非内置模块假定来自第一个模块的对象具有包装器时,这样做天真地给了我段错误。

(如果一切都是在-builtin关闭的情况下进行编译,或者单独使用第二个模块并打开-builtin ,我就永远不会遇到段-builtin ;它只是在将它们与不同的编译选项一起使用时。)

细节

我有几个单独的模块,我使用SWIG。 假设其中一个名为A ,并包含基本对象(四元数)。 因为它包含许多计算中涉及的基本对象,所以我更喜欢使用SWIG的-builtin选项。 我测试了它,这确实在时间上产生了非常显着的差异。

现在,我还有另一个名为B模块,需要使用A对象。 但是B包含大量的脂肪复合物,我不会在很多时候使用它,所以我不认为在这里使用-builtin有很多优点。 此外,我真的想扩展B的类,并做一些用-builtin无法实现的-builtin

问题是我必须在Bi里面%import Ai 但是,为B生成的代码假定A对象具有额外的包装器,而不是使用-builtin 因此,当我使用B ,我会遇到段错误。

(至少,我假设segfaults结果是因为B假定额外的包装器。我查看了我的B_wrap.cpp文件,看到它假设存在这些包装器,但我不能说我做了任何测试确保问题来自哪里。但是段错误只与BA使用相吻合。就其自身而言, A从来没有给我任何麻烦。而且,如果我编译AB没有-builtin ,我从来没有得到段错误。)

原则上,我可以使用MONK的方法 ,只是将我需要添加方法的任何类子类化,同时使用-builtin编译所有-builtin 但是这会破坏我的C ++代码中的名称和我的python代码中的名称之间的良好对应关系,以及要求一组或另一组用户更改他们使用的名称,以及在对接中的一般痛苦。

我为没有MWE而道歉,但我认为这将是一个不合理的大型MWE。

我不知道用单独的标志编译是可能的,但我对MONK的解决方案感到满意。 结合SWIG的%rename功能,MONK的方法不需要重命名用户可见的任何内容。 此外,它易于实现,每个类我只想修改五行。 因此,所有东西都可以用-builtin编译,而且没有段错误。 虽然这在技术上没有回答我在顶部提出的问题,但它适合我。

所以,我们假设B中的关键对象是一个名为Classy的类。 我只是告诉SWIG将其重命名为_Classy (下划线,这样我每次在ipython中使用tab完成时都不必查看它)。 然后,我将创建一个子类,这些子类是那些对象的子类。 最后,我将创建一个名为Classy的新对象, 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'

在最后一行中,类型为Classy的python对象x确实具有一个属性 - 即使C ++类根本没有任何内容。 所以我们成功了。

据推测,这个子类化失败了-builtinClassy对象的速度优势,但我已经决定我不关心那一个类。 另一方面,我可以保留任何我没有显式子类化的对象的速度优势,因此仍然有理由使用builtin

暂无
暂无

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

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