通过SWIG和Python从第三方.dll共享库访问函数

我从第三方获得了一个与他的.lib和.h文件一起发送的DLL(假设文件是​​:“test.dll”,“test.lib”和“test.h”)

这个交付的DLL包含一些我应该从Python脚本访问它们的函数.
为此,我必须使用SWIG和MSVC2010构建扩展(.pyd).
(我将第三方文件复制到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文件的“属性”中,我放了“自定义构建工具” – > “命令行”,如下:

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”文件没有任何问题.我使用相同的文件(没有任何修改)来实现与经典DLL相同的C包装类,并且它运行良好.

项目规格:

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

有人可以帮帮我吗?
任何想法将不胜感激!

谢谢!

解决方法:

尝试在接口文件中包含其他%include之前添加以下内容.

%include <windows.i>

SWIG不会递归到嵌套包含中,这会提供BOOL和_declspec等定义,否则会混淆SWIG.

上一篇:Python .py生成.pyd文件并打包.exe注意事项


下一篇:Python文件.py||.pyi||.pyc||.pyo||.pyd等各种文件后缀区别(全面汇总)