tags:

views:

113

answers:

2

I am trying to wrap a DLL, using its header file, through SWIG. I got a syntax error while processing my interface .i file using SWIG. After tracking down what was the offending line (line number of the printed by SWIG error message did not match the true offending line), I found that the minimum non-processable SWIG interface file is:

/* example.i */
%module example
%{
extern  __declspec(dllimport) INT __cdecl function(int argument);
%}
extern  __declspec(dllimport) INT __cdecl function(int argument);

Where the prototype tern extern __declspec(dllimport) INT __cdecl function(int argument); was obtained from the header file I was trying to wrap.

There are tens of functions declared with this type. As you can see I dont have enough C experience to tell whether this type makes sense. The header file came from the vendor and it compiles OK using Visual C++ 6. Could somebody clarify me?

+1  A: 

Just the INT jumps out as trouble. That's a macro, you'd need like #include <windows.h> to define it. It is very unlikely to be anything else but a regular int. The "extern" is superfluous, any compiler would ignore it.

Hans Passant
WinDef.h does indeed `typedef int INT;`
dan04
I have tried including all combinantion of windows.h and WinDef.h, but no game. I also tried to define INT as int as dan04 described, still nothing. I have tried to wrap another DLL and have found that __cdecl type functions seems to be the trouble. A third attempt with a different DLL was successful in this one there was no __cdecl type.
Bernardo Kyotoku
I dunno, I'd need to see the exact text of an error message and a description of the step that generates it to have any clue what the problem might be. Read this: http://catb.org/esr/faqs/smart-questions.html
Hans Passant
if removing _cdecl worked, it probably means the actual function is getting compiled as C++?
Keith Nicholas
A: 

OK... ended up learning what calling conventions are. The problem was how the SWIG interface file should be written.

/* example.i */
%module example
%{
int __cdecl foo(void);      // function declarations for the function 
int __stdcall foo2(void);   // you intend to wrap goes in here
%}
int foo(void);          // function you want to wrap goes in here
int foo2(void);         // without the calling convention

In the region where the function you want to wrap goes, should not contain the calling convention modifier (_cdecl,_stdcall,etc). But I did not want to remove the calling convention modifiers by hand, specially because I did not want to modify the header file I was trying to wrap (Imagine the vendor releasing new and incompatible version of header file, I would have to modify the header all over again). A solution is to #define the calling convention modifiers away, SWIG already provides a file that contain this #define'tions, the "windows.i". You just have to include it before including the header containing the functions you want to wrap. Like this:

/* example.i */
%module example
%{
#include "example.h"
%}
%include "windows.i"
%include "example.h"

where

/* example.h */
int __cdecl foo(void);
int __stdcall foo2(void);

I just don't understand why it does not do this by default. But I am happy with what I have found. Thank you guys for the pointers...

Bernardo Kyotoku
meh, RTFM!From swig/docs/manual/windows.html"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."
Bernardo Kyotoku