Discussion:
Swig stumbles on __declspec(dllimport)
Antti Karanta
2005-09-05 11:58:23 UTC
Permalink
Hi!

I stumbled into a problem w/ a header file containing func definitions
like this:

#define XPORT __declspec(dllimport)

XPORT void func1(const MYChar *szOpt, MYInt *pnIerr);


Swig gives an error message:

C:\Temp\swigtest>swig -java foo.i
foo.h(13): Error: Syntax error in input.

But generates the wrapper files anyway. However, it leaves out some
functions declared for wrapping in the interface file.

I did a (hopefully) minimal example producing the problem, see below.
In the swig interface file I try to wrap two functions, but only the
first one ends up being wrapped.

Am I doing something wrong or is this a swig bug? Any workarounds?


I'm using swig 1.3.25 on WinXP sp2.



-Antti-



Ps. The same problem occurs w/ __declspec(dllexport), which is to be
expected.

Pps. I tried to attach these example files to my previous mail, but
that mail never showed up on the list so I assume posts w/ attachments
are filtered away. Anyway, here are the two files "inlined":

foo.i:
-->

%module FooBar

// the import is done to introduce the typedefs to swig
%import "foo.h"

void func1(const MYChar *szOpt, MYInt *pnIerr);
void func2(const MYChar *szOpt, MYInt *pnIerr);

<--

foo.h:
-->

#define XPORT __declspec(dllimport)

#ifdef __cplusplus
extern "C"
{
#endif

typedef long MYInt;
typedef double MYDouble;
typedef char MYChar;

XPORT void func1(const MYChar *szOpt, MYInt *pnIerr);
XPORT void func2(const MYChar *szOpt, MYInt *pnIerr);
XPORT void func3(const MYChar *szOpt, MYInt *pnIerr);

#ifdef __cplusplus
}
#endif

<--

_______________________________________________
Swig maillist - ***@cs.uchicago.edu
http://mailman.cs.uchicago.edu/mailman/listinfo/swig
William S Fulton
2005-09-05 12:07:55 UTC
Permalink
Post by Antti Karanta
Hi!
I stumbled into a problem w/ a header file containing func definitions
#define XPORT __declspec(dllimport)
XPORT void func1(const MYChar *szOpt, MYInt *pnIerr);
C:\Temp\swigtest>swig -java foo.i
foo.h(13): Error: Syntax error in input.
But generates the wrapper files anyway. However, it leaves out some
functions declared for wrapping in the interface file.
I did a (hopefully) minimal example producing the problem, see below.
In the swig interface file I try to wrap two functions, but only the
first one ends up being wrapped.
Am I doing something wrong or is this a swig bug? Any workarounds?
This is a known issue as SWIG requires ISO C/C++ which __declspec ain't. Just put

#define XPORT

into your interface file, then SWIG will ignore it as it is not needed when
generating wrappers.

William

_______________________________________________
Swig maillist - ***@cs.uchicago.edu
http://mailman.cs.uchicago.edu/mailman/listinfo/swig
Antti Karanta
2005-09-05 12:37:06 UTC
Permalink
Thanks for a quick answer.
Post by William S Fulton
Post by Antti Karanta
Am I doing something wrong or is this a swig bug? Any workarounds?
This is a known issue as SWIG requires ISO C/C++ which
__declspec ain't. Just put
#define XPORT
into your interface file, then SWIG will ignore it as it is
not needed when generating wrappers.
Putting that line into the interface file foo.i does not solve the
problem:

C:\Temp\swigtest>swig -java foo.i
foo.h(2): Error: Macro 'XPORT' redefined,
foo.i(3): Error: previous definition of 'XPORT'.

But from that I got an idea to try this in the interface file (before
importing the header file):

#define __declspec(dllimport)

and it works great! Now swig thinks __declspec is an empty macro. = )


Thanks a lot for your help.



-Antti-


_______________________________________________
Swig maillist - ***@cs.uchicago.edu
http://mailman.cs.uchicago.edu/mailman/listinfo/swig
Antti Karanta
2005-09-05 13:20:46 UTC
Permalink
-----Original Message-----
Sent: 5. syyskuuta 2005 15:37
Subject: RE: [Swig] Re: Swig stumbles on __declspec(dllimport)
Thanks for a quick answer.
Post by William S Fulton
Post by Antti Karanta
Am I doing something wrong or is this a swig bug? Any
workarounds?
Post by William S Fulton
This is a known issue as SWIG requires ISO C/C++ which
__declspec ain't. Just put
#define XPORT
into your interface file, then SWIG will ignore it as it is
not needed when generating wrappers.
Putting that line into the interface file foo.i does not solve the
C:\Temp\swigtest>swig -java foo.i
foo.h(2): Error: Macro 'XPORT' redefined,
foo.i(3): Error: previous definition of 'XPORT'.
But from that I got an idea to try this in the interface
file (before
#define __declspec(dllimport)
and it works great! Now swig thinks __declspec is an empty
macro. = )
I was a bit too quick about being happy. Swig emitted no error
messages, but when I looked at the wrapper class FooBar.java, there were
no wrapped methods there at all! Running swig w/ -Wall provides some
insight as to what might be wrong:

C:\Temp\swigtest>swig -Wall -java foo.i
foo.i(8): Warning(322): Redundant redeclaration of 'func1',
foo.h(13): Warning(322): previous declaration of 'func1'.
foo.i(9): Warning(322): Redundant redeclaration of 'func2',
foo.h(14): Warning(322): previous declaration of 'func2'.

So it seems that using %import to introduce the typedefs to swig seems
to confuse it as the same file contains headers for the functions to be
wrapped. From page 61 of swig documentation: "%import simply gathers
type information, but doesn't generate wrappers." I thought this means
that if function headers are found, they are ignored. Have I
misunderstood something here?



-Antti-


Ps. Here are the used files for convenience:

foo.i:
-->

%module FooBar

#define __declspec(dllimport)

// the import is done to introduce the typedefs to swig
%import "foo.h"

void func1(const MYChar *szOpt, MYInt *pnIerr);
void func2(const MYChar *szOpt, MYInt *pnIerr);

<--

foo.h
-->


#define XPORT __declspec(dllimport)

#ifdef __cplusplus
extern "C"
{
#endif

typedef long MYInt;
typedef double MYDouble;
typedef char MYChar;

XPORT void func1(const MYChar *szOpt, MYInt *pnIerr);
XPORT void func2(const MYChar *szOpt, MYInt *pnIerr);
XPORT void func3(const MYChar *szOpt, MYInt *pnIerr);

#ifdef __cplusplus
}
#endif

<--






_______________________________________________
Swig maillist - ***@cs.uchicago.edu
http://mailman.cs.uchicago.edu/mailman/listinfo/swig
Marcelo Matus
2005-09-05 18:38:49 UTC
Permalink
You need to ensure that the non-ansi XPORT definition is properly
enabled/disabled, ie, either put it in a config.h file, which detects if
is need it or not.
or everywhere you define it, use something like

-------- foo.h -------

#if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
#define XPORT __declspec(dllimport)
#else
#deifne XPORT
#endif

.....

-------foo.h --------

That will prevent SWIG, and others C++ compilers, to get confused.


Marelo
Post by Antti Karanta
-----Original Message-----
Sent: 5. syyskuuta 2005 15:37
Subject: RE: [Swig] Re: Swig stumbles on __declspec(dllimport)
Thanks for a quick answer.
Post by William S Fulton
Post by Antti Karanta
Am I doing something wrong or is this a swig bug? Any
workarounds?
Post by William S Fulton
This is a known issue as SWIG requires ISO C/C++ which
__declspec ain't. Just put
#define XPORT
into your interface file, then SWIG will ignore it as it is
not needed when generating wrappers.
Putting that line into the interface file foo.i does not solve the
C:\Temp\swigtest>swig -java foo.i
foo.h(2): Error: Macro 'XPORT' redefined,
foo.i(3): Error: previous definition of 'XPORT'.
But from that I got an idea to try this in the interface
file (before
#define __declspec(dllimport)
and it works great! Now swig thinks __declspec is an empty
macro. = )
I was a bit too quick about being happy. Swig emitted no error
messages, but when I looked at the wrapper class FooBar.java, there were
no wrapped methods there at all! Running swig w/ -Wall provides some
C:\Temp\swigtest>swig -Wall -java foo.i
foo.i(8): Warning(322): Redundant redeclaration of 'func1',
foo.h(13): Warning(322): previous declaration of 'func1'.
foo.i(9): Warning(322): Redundant redeclaration of 'func2',
foo.h(14): Warning(322): previous declaration of 'func2'.
So it seems that using %import to introduce the typedefs to swig seems
to confuse it as the same file contains headers for the functions to be
wrapped. From page 61 of swig documentation: "%import simply gathers
type information, but doesn't generate wrappers." I thought this means
that if function headers are found, they are ignored. Have I
misunderstood something here?
-Antti-
-->
%module FooBar
#define __declspec(dllimport)
// the import is done to introduce the typedefs to swig
%import "foo.h"
void func1(const MYChar *szOpt, MYInt *pnIerr);
void func2(const MYChar *szOpt, MYInt *pnIerr);
<--
foo.h
-->
#define XPORT __declspec(dllimport)
#ifdef __cplusplus
extern "C"
{
#endif
typedef long MYInt;
typedef double MYDouble;
typedef char MYChar;
XPORT void func1(const MYChar *szOpt, MYInt *pnIerr);
XPORT void func2(const MYChar *szOpt, MYInt *pnIerr);
XPORT void func3(const MYChar *szOpt, MYInt *pnIerr);
#ifdef __cplusplus
}
#endif
<--
_______________________________________________
http://mailman.cs.uchicago.edu/mailman/listinfo/swig
_______________________________________________
Swig maillist - ***@cs.uchicago.edu
http://mailman.cs.uchicago.edu/mailman/listinfo/swig
William S Fulton
2005-09-05 21:46:59 UTC
Permalink
Post by Marcelo Matus
You need to ensure that the non-ansi XPORT definition is properly
enabled/disabled, ie, either put it in a config.h file, which detects if
is need it or not.
or everywhere you define it, use something like
-------- foo.h -------
#if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
#define XPORT __declspec(dllimport)
#else
#deifne XPORT
#endif
.....
-------foo.h --------
That will prevent SWIG, and others C++ compilers, to get confused.
Marelo
Post by Antti Karanta
-----Original Message-----
On Behalf Of Antti Karanta
Sent: 5. syyskuuta 2005 15:37
Subject: RE: [Swig] Re: Swig stumbles on __declspec(dllimport)
Thanks for a quick answer.
Post by William S Fulton
Post by Antti Karanta
Am I doing something wrong or is this a swig bug? Any
workarounds?
Post by William S Fulton
This is a known issue as SWIG requires ISO C/C++ which __declspec
ain't. Just put
#define XPORT
into your interface file, then SWIG will ignore it as it is not
needed when generating wrappers.
Putting that line into the interface file foo.i does not solve the
C:\Temp\swigtest>swig -java foo.i
foo.h(2): Error: Macro 'XPORT' redefined,
foo.i(3): Error: previous definition of 'XPORT'.
But from that I got an idea to try this in the interface file (before
#define __declspec(dllimport)
and it works great! Now swig thinks __declspec is an empty macro. = )
I was a bit too quick about being happy. Swig emitted no error
messages, but when I looked at the wrapper class FooBar.java, there were
no wrapped methods there at all! Running swig w/ -Wall provides some
C:\Temp\swigtest>swig -Wall -java foo.i
foo.i(8): Warning(322): Redundant redeclaration of 'func1',
foo.h(13): Warning(322): previous declaration of 'func1'.
foo.i(9): Warning(322): Redundant redeclaration of 'func2',
foo.h(14): Warning(322): previous declaration of 'func2'.
So it seems that using %import to introduce the typedefs to swig seems
to confuse it as the same file contains headers for the functions to be
wrapped. From page 61 of swig documentation: "%import simply gathers
type information, but doesn't generate wrappers." I thought this means
that if function headers are found, they are ignored. Have I
misunderstood something here?
-Antti-
-->
%module FooBar
#define __declspec(dllimport)
// the import is done to introduce the typedefs to swig
%import "foo.h"
void func1(const MYChar *szOpt, MYInt *pnIerr);
void func2(const MYChar *szOpt, MYInt *pnIerr);
<--
foo.h
-->
#define XPORT __declspec(dllimport)
#ifdef __cplusplus
extern "C"
{
#endif
typedef long MYInt;
typedef double MYDouble;
typedef char MYChar;
XPORT void func1(const MYChar *szOpt, MYInt *pnIerr);
XPORT void func2(const MYChar *szOpt, MYInt *pnIerr);
XPORT void func3(const MYChar *szOpt, MYInt *pnIerr);
#ifdef __cplusplus
}
#endif
The func1 and func2 methods are marked as being imported as they are
parsed as being imported (ie not wrapped) first.

Either use %include to wrap the entire header file or copy the bits out
of the header file that you want into the interface file and don't use
%import. %import is really designed for producing multiple modules from
multiple invocations of SWIG.

Try this next:

%module FooBar

%{
#include "foo.h"
%}

// Methods that you don't want wrapped follow:
%ignore func3;

#define __declspec(dllimport)
%include "foo.h"

William
_______________________________________________
Swig maillist - ***@cs.uchicago.edu
http://mailman.cs.uchicago.edu/mailman/listinfo/swig
Antti Karanta
2005-09-06 06:16:17 UTC
Permalink
Post by Marcelo Matus
Post by Marcelo Matus
You need to ensure that the non-ansi XPORT definition is properly
enabled/disabled, ie, either put it in a config.h file,
which detects if
Post by Marcelo Matus
is need it or not.
or everywhere you define it, use something like
-------- foo.h -------
#if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
#define XPORT __declspec(dllimport)
#else
#deifne XPORT
#endif
.....
-------foo.h --------
That will prevent SWIG, and others C++ compilers, to get confused.
That is (about) how it is in the real header file I'm using. The
problem is that our build script passes all the defines (-D) that the
compiler gets to swig, too. That is because they affect the typedefs and
therefore possibly the generated wrapper code.
I could use the fact that SWIG is defined when swig runs to play w/
this, but as you can see below, this is not really the problem. If it
was, putting
#define __declspec(ignoredarg)
in the .i file before doing the import works fine.
Post by Marcelo Matus
The func1 and func2 methods are marked as being imported as they are
parsed as being imported (ie not wrapped) first.
Either use %include to wrap the entire header file or copy
the bits out
of the header file that you want into the interface file and
don't use
%import. %import is really designed for producing multiple
modules from
multiple invocations of SWIG.
%module FooBar
%{
#include "foo.h"
%}
%ignore func3;
#define __declspec(dllimport)
%include "foo.h"
Well, it would work w/ this simple example, but the real header file
I'm figting w/ contains about a hundred funcs of which I only want to
wrap 10-20. And it's not even that simple - I have to use %apply on
several of them to apply the correct typemaps.

So, I guess I'll just copy-paste the necessary typedefs into the .i
file. I wanted to avoid this as it may give headaches later during
maintenance if the originals change and nobody remembers to update the
copies in the .i file(s). = /

Thanks for your help.



-Antti-



Ps. Despite these minor problems I have to say swig is a real life
saver - I don't think I would have survived all the JNI stuff I have had
to make without it. = )




_______________________________________________
Swig maillist - ***@cs.uchicago.edu
http://mailman.cs.uchicago.edu/mailman/listinfo/swig

Loading...