是否可以拆分SWIG模块进行编译,但在链接时重新加入?

时间:2009-03-30 15:40:19

标签: c++ python swig

大约两年前,当我第一次实现SWIG绑定时,我遇到了这个问题。一旦我们暴露了大量的代码,我们就到了SWIG输出C ++文件这么大的程度,编译器无法处理它们。解决这个问题的唯一方法是将接口分成多个模块并单独编译。

这有几个缺点:

•每个模块必须了解其他模块中的依赖关系。我有一个脚本来生成处理这方面的接口文件,但它增加了额外的复杂性。

•每个附加模块都会增加动态链接器加载代码所需的时间。我添加了一个导入所有子模块的 init .py文件,因此代码拆分的事实对用户来说是透明的,但总是可见的是加载时间很长。

我目前正在审核我们的构建脚本/构建过程,我想看看我是否能找到一个比现在更好的问题的解决方案。理想情况下,我有一个包含所有包装器代码的共享库。

有谁知道如何用SWIG实现这一目标?我已经看到一些用Ruby编写的自定义代码用于特定项目,其中输出经过后处理以实现这一点,但是当我查看Python包装器的可行性时,它看起来并不那么容易。

2 个答案:

答案 0 :(得分:1)

我刚刚为TCL库做了相同的黑客攻击:我使用了几个SWIG模块,生成几个.cpp文件,这些文件在几个.o文件中编译,但是将它们全部编译在一个由单个TCL加载的.so文件中# 34;负载"命令。

这个想法是创建一个调用所有子模块(Sub1和Sub2)的初始化函数的顶部swig模块(Top):

%module Top
%header %{
  extern "C" {
    SWIGEXPORT int Sub1_Init(Tcl_Interp *);
    SWIGEXPORT int Sub2_Init(Tcl_Interp *);
  }
%}
%init %{
    if (Sub1_Init(interp) != TCL_OK) {return TCL_ERROR;}
    if (Sub2_Init(interp) != TCL_OK) {return TCL_ERROR;}
%}

子模块文件中没有什么特别之处。 我最终得到文件Top.so,我从TCL加载命令" load ./Top.so"

我不了解python,但可能很相似。但是,您可能需要了解如何加载python扩展。

答案 1 :(得分:0)

如果正确拆分,模块不一定需要具有与其他模块相同的依赖关系 - 只需要进行编译即可。如果你适当地分解,你可以拥有没有循环依赖的库。使用多个库的问题是,默认情况下,SWIG静态地声明其运行时代码,因此,将对象从一个模块传递到另一个模块时出现问题。您需要启用SWIG运行时代码的共享版本。

从文档(SWIG网页文档链接中断):

  

运行时函数是私有的   每个SWIG生成的模块。那是,   声明了运行时函数   具有“静态”连接并且可见   仅限于定义的包装函数   在那个模块中。唯一的问题   这种方法是当超过   一个SWIG模块用于同一个   应用程序,这些模块经常需要   分享类型信息。这是   尤其适用于C ++程序   SWIG必须收集和分享   有关继承的信息   跨越模块的关系   边界。

查看下载文档中的该部分(第16.2节SWIG运行时代码),它将为您提供有关如何启用此功能的详细信息,以便在从一个模块传递到另一个模块时可以正确处理对象。

FWIW,我没有使用过Python SWIG,但已经完成了Tcl SWIG。