4
votes

I have from a third party a DLL delivered together with his .lib and .h files (let's say the files are: "test.dll", "test.lib" and "test.h")

This delivered DLL contains some functions that I should access them from a Python script. For this, I must build an extension (.pyd) using SWIG and MSVC2010. (I copy the third party files into the MSVC project's directory)

To have an overview about "test.h" file, this is how it looks like (for simplicity, I put only one function, "CreateFile()", which returns a file handle):

/* 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

I intend to make a class to wrap those third party functions (implemented in "test.dll" library). The "myInterface.h" file looks like this:

/* 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

};

...and the implementation of the class, I put it into "myInterface.cxx" file:

/* 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;
}

To use SWIG, I must add into the MSVC project the following SWIG interface file .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"

In the MSVC project, in the "Properties" of this .i file, I put on "Custom Build Tool" -> "Command Line", the following:

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)"

OK! When I try to build the PYD extension, I've got this error:

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

...but there is nothing wrong with "test.h" file. I use the same file (without any modifications) to implement the same C++ wrapper class as a classic DLL and it works well.

Project specs:

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

Could anyone help me, please? Any idea will be appreciated!

Thank you!

1
so with header-file, dll file and swig, can we generate python wrappers?bicepjai

1 Answers

6
votes

Try adding the following before your other %includes in your interface file.

%include <windows.i>

SWIG doesn't recurse into nested includes, and this provides definitions such as BOOL and _declspec that otherwise confuse SWIG.