代码改变世界

在VC++6.0中使用swig生成Python扩展的配置

2009-02-23 13:57  ubunoon  阅读(2620)  评论(0编辑  收藏  举报
在SWIG官网上的教程:

In Developer Studio, SWIG should be invoked as a custom build option. This is usually done as follows:

  • Open up a new workspace and use the AppWizard to select a DLL project.
  • Add both the SWIG interface file (the .i file), any supporting C files, and the name of the wrapper file that will be created by SWIG (ie. example_wrap.c). Note : If using C++, choose a different suffix for the wrapper file such as example_wrap.cxx. Don't worry if the wrapper file doesn't exist yet--Developer Studio keeps a reference to it.
  • Select the SWIG interface file and go to the settings menu. Under settings, select the "Custom Build" option.
  • Enter "SWIG" in the description field.
  • Enter "swig -python -o $(ProjDir)\$(InputName)_wrap.c $(InputPath)" in the "Build command(s) field"
  • Enter "$(ProjDir)\$(InputName)_wrap.c" in the "Output files(s) field".
  • Next, select the settings for the entire project and go to "C++:Preprocessor". Add the include directories for your Python installation under "Additional include directories".
  • Define the symbol __WIN32__ under preprocessor options.
  • Finally, select the settings for the entire project and go to "Link Options". Add the Python library file to your link libraries. For example "python21.lib". Also, set the name of the output file to match the name of your Python module, ie. _example.pyd - Note that _example.dll also worked with Python-2.4 and earlier.
  • Build your project.
在DS中,SWIG需要被导入到custom build option中,通常采用下面的方式
1、打开新的workspace,使用AppWizard想到选择一个Dll工程
2、把SWIG接口文件(.i文件),任何支持的C文件,以及封装的文件名(由SWIG创建,例如example_wrap.c)。注意:如果使用C++,为封装文件选择不同的后缀名,如example_wrap.cxx,不要担心,如果wrapper文件不存在,DS保持对他的引用。
3、选择SWIG接口文件(.i),进入settings菜单(右键-settings),在settings中,选择“Custom Build”选项
4、在Description Field(描述域)中输入SWIG
5、在“Build command(s) field”(构建命名域)中输入"swig -python -o $(ProjDir)\$(InputName)_wrap.c $(InputPath)"
6、选择整个工程的settings(project-settings),进入C++:Preprocessor选项中,在Additional include directories中输入Python安装的目录中的include(其实不必这样设置,可以在整个vs环境中就将Python的include环境配置进去。如何配置整个include环境,见下面后注。
7、定义在预处理选项上定义__WIN32__宏
8、最后,选择整个工程的settings,进入Link Options,添加Python库文件到链接文件中,例如"python21.lib"(现在一般都用python25.lib,在python安装目录下的libs中),同时,设置输出文件名为Python模块支持的方式,如_example.pyd——注意_example.dll在Python2.4和之前版本均支持。
8、创建project

后注:
     如果你一老一实的那么做,你很有可能会失败,主要失败点在:
1、Python的library库没有导入:最佳的做法是在tool-options-directory中添加include文件和library文件
2、如果你把swig的执行目录也放在上面的directory中,也有可能会失败,我就是因为这个,导致很久都没有运行,建议放在环境变量的path目录下面
3、建议你在第一次构建的时候不要导入封装的文件名,第一次构建完毕后,会在当前目录下(依据你的配置),生成一个封装文件名,这个时候,你在导入封装文件名,可以省去封装名错误的问题!然后再编译一下就完成了封装
4、Python安装目录下的libs只有PythonXX.lib,支持的是Release版本的PythonXX.dll,因此,最好是采用Release版本来编译,这样在运行时就不会有错误。
5、注意,配置工程文档时要注意debug与Release都需要配置,否则,也有可能出现错误

swig是一个不错的工具,用来封装C/C++编写的代码到其他程序中,非常不错!

对于C编译器,上面的方法毫无问题,但是对于VC6.0下面使用C++来导出函数使用的时候,将会出现很多问题,尤其是与extern "C" __declspec (dllimport)和__stdcall 支持时候的库导出时,将会遇到很多问题。

下面是一个解决方法:
1、将__declspec(dllimport) 和__stdcall 定义的宏屏蔽掉,如已经存在:
#define DLLIMPORT __declspec(dllimport)
#define WINAPI __stdcall

这个时候,如果直接使用swig,那么将会出现错误。因为swig支持的是ANSI C/C++,对于这些在Windows下的扩展是不支持的,将上面语句注释掉,然后新建两个空宏
#define DLLIMPORT
#define WINAPI
注意,如果是系统定义的,如WINAPI,CALLBACK,可以先将这些宏申明去除,在重新定义
#undef WINAPI
#define WINAPI

2、编写interface文件,将正确的interface文件编译后,会出现link错误,这是正常的,因为前面已经屏蔽了。

3、要感谢make的作用,这个时候,你修改导入库的其他函数,接口文件不会再次被编译,也就是不错再次生成封装包的文件(cpp文件),于是再将导入库中的函数调用方式修改回来

4、再次编译,你将获得正确的编译结果,需要注意的是,如果你修改了interface文件,那么就一定要把宏重新屏蔽掉,否则仍旧会有错误存在,只有当你确认没有错误的时候,才可以使用最初定义的导出,导出方式。

此方法对C编译器(MSVC)无用!反而会出现大量错误!!!

make fun!

如一个实例为:
swig.i文件:
%module opencv

%include cxcore.i
%include cv.i

cxcore.i文件为:
%{
    #include <cxcore.h>
%}
%include "cxcore.h"

cv.i文件为:
%{
    #include <cv.h>
%}
%include "cv.h"

但要注意的是,cxcore文件中的一些函数指针需要通过另外的方式解决,swig无法识别这些函数内容