python - 使用 SWIG 包装 C/C++ 库

标签 python c++ swig cython topaz-signatures

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

Topaz 提供了一个“C”库 (http://www.topazsystems.com/sigpluslibrary.html) 用于连接他们的设备。我相信我已经确定它实际上是 C++(使用类和其他 C++ 构造)。我曾尝试使用 SWIG 和 Cython 为 Python 创建包装器,但运气并不好。

我的 SWIG 目录结构是这样的:

  • 西格斯威格
    • 包括(包含 Topaz 共享 C 库中的所有 header )
    • setup.py
    • SigLib.i
    • 签名.i
    • 等...

设置.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

签名.i

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

我很难理解 SWIG 示例,但据我所知这应该没问题。 SigLib.i 载入主头文件 (SigLib.h),其中包括 SIGAPI 声明和所有主要包含文件。它不包括 Signature.h(或其他接口(interface)文件中的任何其他 header ),因为它不遵循所有 header 。然后加载额外的接口(interface)文件。 Signature.i 和所有其他接口(interface)文件仅包含对要解析的 header 的引用。

我尝试了几种不同的方法,这似乎是迄今为止最好的。但是,当我执行 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 似乎是一个 #define,它出现在 SigLib.h 文件中,并用于类定义中,例如:

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。

最佳答案

来自 SWIG 文档的第 3.4 段:

A common problem when using SWIG on Windows are the Microsoft function calling conventions which are not in the C++ standard. SWIG parses ISO C/C++ so cannot deal with proprietary conventions such as __declspec(dllimport), __stdcall etc. There is a Windows interface file, windows.i, to deal with these calling conventions though. The file also contains typemaps for handling commonly used Windows specific types such as __int64, BOOL, DWORD etc. Include it like you would any other interface file, for example:

%include <windows.i>

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

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

关于python - 使用 SWIG 包装 C/C++ 库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29394563/

相关文章:

c++ - 通过链表添加多项式

c++ - 检查正确的输入会导致无限循环

python - SWIG 将 C 库连接到 Python(从 C 'iterable' 结构创建 'sequence' Python 数据类型)

python - SWIG python 初始化指向 NULL 的指针

python - Snakemake:通配符不存在时出错

python - Raspberry Pi 上的 py.test 和 pytest : Differences ?

c++ - 从未调用过 Win32 ListBox WNDPROC

c++ - 如何在 Visual Studio 2010 中构建这个简单的 C++/SWIG/C# 项目?

Python:高精度 time.sleep

python - Pandas:在列的应用函数中使用索引值