用SWIG包装C / C ++库

时间:2015-04-01 15:15:01

标签: python c++ swig cython topaz-signatures

我有一个我正在研究的项目,需要使用Topaz Signature Capture pad。我们的产品目前使用Topaz提供的ActiveX控件来收集网站上的签名,但我们正在尝试迁移到由Python提供支持的桌面应用程序。 Python将允许我们在没有太多额外工作的情况下扩展到多个操作系统。

黄玉提供了一个' C'库(http://www.topazsystems.com/sigpluslibrary.html)用于与其设备连接。我相信我已经确定它实际上是C ++(使用类和其他C ++构造)。我曾尝试使用SWIG和Cython为Python创建一个包装器,但我没有太多运气。

我的SWIG目录结构如下:

  • SigSwig
    • 包含(包含Topaz Shared C Library中的所有标头)
    • setup.py
    • SigLib.i
    • Signature.i
    • 等...

Setup.py

# setup.py
import distutils
from distutils.core import setup, Extension

module = Extension(
                        "_SigLib", 
                        ["SigLib.i"],
                        swig_opts=['-c++'],
                        language='c++',
                        library_dirs=['c:\Python27'],
                        libraries=["SigLib", "hid", "LibJpeg", "libtiff", "WINTAB32", "WNTAB32X", "zlib"],
                        extra_options=["SigLib.lib", "hid.lib", "LibJpeg.lib", "libtiff.lib", "WINTAB32.LIB", "WNTAB32X.LIB", "zlib.lib"]
                    )

setup(
      name = "Signature Capture",
      version = "1.0",
      ext_modules = [module]
)

SigLib.i

%module SigLib
%{
#define SIGAPI 
#include "Include\SigLib.h"
%}

%include TabletParameters.i
%include TabletInterface.i
%include LCDInterface.i
%include Signature.i

Signature.i

%module Signature
%include "Include\Signature.h"

我很难跟踪SWIG的例子,但从我所知道的情况来看,这应该没问题。 SigLib.i加载主标题(SigLib.h),其中包括SIGAPI的声明和所有主要包含文件。它不包含Signature.h(或其他接口文件中的任何其他标头),因为它不跟随所有标头。然后它加载其他接口文件。 Signature.i和所有其他接口文件只包含对要解析的标头的引用。

我尝试了几种不同的方式,这似乎是目前为止最好的方式。但是,当我执行setup.py时,我收到了以下错误:

SigLib_wrap.cpp(3417) : error C2065: 'temp' : undeclared identifier
SigLib_wrap.cpp(3418) : error C2065: 'temp' : undeclared identifier
SigLib_wrap.cpp(3418) : error C2059: syntax error : '*'
SigLib_wrap.cpp(3419) : error C2513: 'TabletParameters' : no variable declared before '='
SigLib_wrap.cpp(3419) : error C2065: 'temp' : undeclared identifier
SigLib_wrap.cpp(3420) : error C2065: 'temp' : undeclared identifier
SigLib_wrap.cpp(3420) : error C2541: 'delete' : cannot delete objects that are not pointers
SigLib_wrap.cpp(3432) : error C2275: 'TabletParameters' : illegal use of this type as an expression c:\users\kevin\downloads\sigpython\include\TabletParameters.h(18) : see declaration of 'TabletParameters'

查看生成的代码,大多数错误都包含SIGAPI,如下所示:

SIGAPI * temp;

SIGAPI似乎是SigLib.h文件中出现的#define,用于类定义,如:

class SIGAPI Signature

SigLib.h定义:

#ifdef  SIGLIBDLL
#define SIGAPI  __declspec( dllexport ) 
#else
#define SIGAPI
#endif

我已经尝试了几个小时的谷歌搜索试图找到解决方案,但我没有运气。我还没有在SWIG文档中找到任何内容,但老实说我真的不确定要查找什么。

编辑:

除了加载额外的标题外,Giorgos建议进行更改。它似乎现在生成整个包装文件,包含所有需要的东西,但是链接到库时会出错。

SigLib.i

%module SigLib
%{
    #include "Include\SigLib.h"
%}


%include <windows.i>
%include "Include\SigLib.h"
%include "Include\SigPoint.h"
%include "Include\SigStroke.h"
%include "Include\TabletParameters.h"
%include "Include\CircularBuffer.h"
%include "Include\SerialIoIF.h"
%include "Include\HidIoIF.h"
%include "Include\UsbIoIF.h"
%include "Include\SocketIoIF.h"
%include "Include\NewSocketIoIF.h"
%include "Include\SimIoIF.h"
%include "Include\ProcessSerialData.h"
%include "Include\CaptureSig.h"
%include "Include\TabletPoint.h"
%include "Include\PointBuffer.h"
%include "Include\TabletInterface.h"
%include "Include\TabletSampleList.h"
%include "Include\SigWindowType.h"
%include "Include\SigFile.h"
%include "Include\md5.h"
%include "Include\Utilities.h"
%include "Include\HotSpot.h"
%include "Include\HotSpotList.h"
%include "Include\BitmapCharacter.h"
%include "Include\CharacterMap.h"
%include "Include\TiffImage.h"
%include "Include\LCDGraphicBitmap.h"
%include "Include\LCDInterface.h"

我这样做了,并改变了我装入所有内容的方式。现在它似乎正在编译,但我收到了很多像这样的链接错误:

SigLib_wrap.obj : error LNK2019: unresolved external symbol "public: int __thiscall TabletInterface::PointsInPointBuffer(void)" (?PointsInPointBuffer@TabletInterface@@QAEHXZ) referenced in function __wrap_TabletInterface_PointsInPointBuffer

SigLib_wrap.obj : error LNK2019: unresolved external symbol "public: void __thiscall TabletInterface::InitProcessInputData(void)" (?InitProcessInputData@TabletInterface@@QAEXXZ) referenced in function __wrap_TabletInterface_InitProcessInputData

SigLib_wrap.obj : error LNK2019: unresolved external symbol "public: void __thiscall TabletInterface::CloseProcessInputData(void)" (?CloseProcessInputData@TabletInterface@@QAEXXZ) referenced in function __wrap_TabletInterface_CloseProcessInputData

我需要链接SigLib.lib和其他一些lib文件,但是我不知道如何从我拥有的setup.py文件中做到这一点,如果它甚至适用于Python。

1 个答案:

答案 0 :(得分:1)

来自SWIG文件的第3.4段:

  

在Windows上使用SWIG时常见的问题是Microsoft功能   调用不在C ++标准中的约定。 SWIG解析ISO   因此,C / C ++无法处理诸如此类的专有约定   __declspec(dllimport),__ stdcall等。虽然有一个Windows接口文件windows.i来处理这些调用约定。该   文件还包含用于处理常用Windows的文字映射   特定类型,如__int64,BOOL,DWORD等。包括它像你一样   任何其他接口文件,例如:

%include <windows.i>

__declspec(dllexport) ULONG __stdcall foo(DWORD, __int32);

在任何特定于Windows的声明之前添加%include <windows.i>可能会解决您的问题。