Working from:
- Is ignoring __attribute__((packed)) always safe in SWIG interfaces?
- Visual C++ equivalent of GCC's __attribute__ ((__packed__))
My .i
does:
#define __attribute__(x)
then uses %include to include my cross-platform definition of PACK():
#if defined(SWIG)
#define PACK(...) VA_ARGS
#elif defined(_MSC_VER)
#define PACK(__Decl__) __pragma(pack(push, 1)) __Decl__ __pragma(pack(pop))
#else // GCC
#define PACK(__Decl__) __Decl__ __attribute__ ((packed))
#endif
Then I have code like:
PACK(
typedef struct {
uint8_t something;
uint32_t more;
} ) aName;
With earlier versions of the PACK()
macro, I got syntax error from SWIG on the typedef
line. Now I get past that but when compiling the SWIG-generated .c
file, I have get and set functions that complain aName
doesn't exist. The messages are like (edited):
libudr_perl_swig.c: In function '_wrap_aName_set':
libudr_perl_swig.c:2367:20: error: expected identifier or '(' before
'=' token libudr_perl_swig.c: In function '_wrap_aName_get':
libudr_perl_swig.c:2377:3: error: expected expression before 'aName'
SWIG sort of seems to know about my struct -- it creates access functions -- but the doesn't expose them enough that the access functions can find it.
Before I started to make this cross-platform -- when it was still Linux-only with __attribute__ ((packed))
-- it worked in SWIG. And it still works in Linux. So there appears to be something about SWIG's interpretation of PACK()
that is flawed.
The old way generated a lot of per-field code like:
XS(_wrap_aName_something_set) {
{
aName *arg1 = (aName *) 0 ;
...
the new way generates a little per-struct code like:
SWIGCLASS_STATIC int _wrap_aName_set(pTHX_ SV* sv, MAGIC * SWIGUNUSEDPARM(mg)) {
MAGIC_PPERL
{
Why should my PACK()
(which should be a no-op in SWIG) do that?