Доступ к функциям из сторонней общей библиотеки .dll через SWIG и Python

У меня есть сторонняя DLL, поставляемая вместе с его файлами .lib и .h (скажем, файлы: «test.dll», «test.lib» и «test.h»)

Эта доставленная DLL содержит некоторые функции, к которым я должен получить доступ из скрипта Python. Для этого я должен создать расширение (.pyd), используя SWIG и MSVC2010. (Я копирую сторонние файлы в каталог проекта MSVC)

Чтобы иметь общее представление о файле «test.h», вот как он выглядит (для простоты я поместил только одну функцию «CreateFile()», которая возвращает дескриптор файла):

/* File : test.h */

#if !defined ( TEST_H )
       #define TEST_H

#if defined ( _MSC_VER )
  #pragma warning( disable: 4103)
  #pragma pack( push, 8)
#elif defined ( __BORLANDC__ )
  #pragma option push -a8
  #pragma nopushoptwarn
  #pragma nopackwarning
#endif

#include <wtypes.h>

/*----------------------------------------------------------------------------
| BL API
-----------------------------------------------------------------------------*/
#if defined ( DLL_EXPORTS )
  #define BLAPI( ret)                        ret __stdcall
#else
  #define BLAPI( ret) __declspec( dllimport) ret __stdcall
#endif

/*----------------------------------------------------------------------------
| API
-----------------------------------------------------------------------------*/
#if defined ( __cplusplus )
extern "C" {
#endif

BLAPI( HANDLE) CreateFile( LPCTSTR lpFileName, DWORD dwDesiredAccess);

#if defined ( __cplusplus )
}
#endif


/*----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------*/

#if defined ( _MSC_VER )
  #pragma pack( pop)
#elif defined ( __BORLANDC__ )
  #pragma option pop
  #pragma nopushoptwarn
  #pragma nopackwarning
#endif

#endif // TEST_H

Я намерен создать класс для переноса этих сторонних функций (реализованных в библиотеке test.dll). Файл «myInterface.h» выглядит следующим образом:

/* File : myInterface.h */

#include <windows.h>
#include "test.h"           // <--- third party header

class myInterfaceClass {
public:
    myInterfaceClass() {
    }

    virtual ~myInterfaceClass() {
    };

    HANDLE  hFile;
    BOOL    errorCode;

    BOOL    OpenFile( LPCTSTR lpFileName );  // <-- function wrapper

};

... и реализацию класса я поместил в файл "myInterface.cxx":

/* File : myInterface.cxx */

#include "myInterface.h"
#include "test.h"           // <--- third party header
#include <windows.h>

BOOL myInterfaceClass::OpenFile( LPCTSTR lpFileName )
{
    errorCode = TRUE;
    // open file
    hFile = CreateFile(lpFileName, GENERIC_READ);   // <--- third party function call
    errorCode = ( INVALID_HANDLE_VALUE == hFile);

    return errorCode;
}

Чтобы использовать SWIG, я должен добавить в проект MSVC следующий файл интерфейса SWIG .i:

/* File : myInterface.i */
%module myInterface

%{
#include "myInterface.h"
#include "test.h"
%}

/* Let's just grab the original header file here */
%include "myInterface.h"
%include "test.h"

В проекте MSVC в "Свойствах" этого файла .i я поставил "Custom Build Tool" -> "Command Line" следующее:

echo PYTHON_INCLUDE: %PYTHON_INCLUDE% 
echo PYTHON_LIB: %PYTHON_LIB% 

rem
rem WARNING!: Use quotes (" ") on path names to avoid errors !
rem

echo on 
echo. 
echo. "%(FullPath)"
echo. 
"%SWIG_PATH%\swig.exe" -c++ -python -I%SWIG_PATH%\lib  -Itest "%(FullPath)"

ХОРОШО! Когда я пытаюсь создать расширение PYD, у меня возникает эта ошибка:

Error   1   error : Syntax error in input(1).   D:\ADXWorkZone\testSwig\test.h  33  1   myInterface

... но в файле "test.h" нет ничего плохого. Я использую тот же файл (без каких-либо изменений) для реализации того же класса-оболочки C++, что и классическая DLL, и он работает хорошо.

Спецификации проекта:

Properties -> C/C++ -> General -> Additional Include Directories: $(PYTHON_INCLUDE)
Properties -> Linker -> General -> Output File: _myInterface.pyd
Properties -> Linker -> Input -> Additional Dependencies: $(PYTHON_LIB);test.lib

Кто-нибудь может мне помочь, пожалуйста? Любая идея будет оценена!

Благодарю вас!


person roadx    schedule 09.04.2012    source источник
comment
Итак, с заголовочным файлом, файлом dll и swig, можем ли мы сгенерировать обертки python?   -  person bicepjai    schedule 15.04.2015


Ответы (1)


Попробуйте добавить следующее перед другими %includes в файле интерфейса.

%include <windows.i>

SWIG не рекурсивно входит во вложенные включения, и это обеспечивает такие определения, как BOOL и _declspec, которые иначе сбивают с толку SWIG.

person Mark Tolonen    schedule 09.04.2012
comment
Ты мужчина! Спасибо! Это работает! Большой! Два дня борьбы ни за что. Я знал, что это из интерфейса SWIG, но понятия не имел, откуда. Теперь у меня есть... :) СПАСИБО! - person roadx; 10.04.2012
comment
Пожалуйста! Не забудьте отметить ответ галочкой, если он был вам полезен. - person Mark Tolonen; 10.04.2012