У меня есть проект, над которым я работаю, и который требует использования планшета Topaz Signature Capture. В настоящее время наш продукт использует элемент управления ActiveX, предоставленный Topaz, для сбора подписей на веб-сайте, но мы пытаемся перейти к настольному приложению на основе Python. Python позволит нам разветвляться на несколько ОС без особой работы.
Topaz предоставляет библиотеку ‘C’ (http://www.topazsystems.com/sigpluslibrary.html) для взаимодействия с их устройствами. Я считаю, что я определил, что это на самом деле C ++ (использует классы и другие конструкции C ++). Я пытался создать оболочку для Python, используя SWIG и Cython, но мне не очень повезло.
Моя структура каталогов для SWIG такова:
# 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]
)
%module SigLib
%{
#define SIGAPI
#include "Include\SigLib.h"%}
%include TabletParameters.i
%include TabletInterface.i
%include LCDInterface.i
%include 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 представляется #define
происходит в файле SigLib.h и используется в определениях классов, таких как:
class SIGAPI Signature
SigLib.h определение:
#ifdef SIGLIBDLL
#define SIGAPI __declspec( dllexport )
#else
#define SIGAPI
#endif
Я пытался часами поискать в Google, чтобы найти решение этой проблемы, но мне не повезло. Я не смог ничего найти в документации SWIG, но, честно говоря, я не совсем уверен, что искать.
Редактировать:
Внесены изменения, предложенные Giorgos в дополнение к загрузке в дополнительные заголовки. Похоже, что теперь он генерирует весь файл переноса со всем необходимым, но получает ошибки, связанные с библиотеками.
%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.
Из пункта 3.4 документации SWIG:
Распространенной проблемой при использовании SWIG в Windows является функция 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);
Добавление %include <windows.i>
прежде чем любые конкретные объявления Windows, вероятно, решат вашу проблему.