为啥 Perl 对跨平台打包结构的访问不适用于 SWIG?
Posted
技术标签:
【中文标题】为啥 Perl 对跨平台打包结构的访问不适用于 SWIG?【英文标题】:Why does Perl access to cross-platform packed structs not work with SWIG?为什么 Perl 对跨平台打包结构的访问不适用于 SWIG? 【发布时间】:2014-06-12 16:10:05 【问题描述】:工作地点:
Is ignoring __attribute__((packed)) always safe in SWIG interfaces? Visual C++ equivalent of GCC's __attribute__ ((__packed__))我的.i
会:
#define __attribute__(x)
然后使用 %include 包含我对 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
然后我有这样的代码:
PACK(
typedef struct
uint8_t something;
uint32_t more;
) aName;
使用早期版本的 PACK()
宏,我在 typedef
行上收到来自 SWIG 的语法错误。现在我解决了这个问题,但是在编译 SWIG 生成的 .c
文件时,我得到并设置了抱怨 aName
不存在的函数。消息就像(已编辑):
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 似乎知道我的结构——它创建了访问函数——但并没有充分暴露它们,以至于访问函数可以找到它。
在我开始制作这个跨平台之前——当时它还只是带有__attribute__ ((packed))
的 Linux——它在 SWIG 中工作。它仍然适用于 Linux。因此,SWIG 对PACK()
的解释似乎存在缺陷。
旧方法会生成很多每个字段的代码,例如:
XS(_wrap_aName_something_set)
aName *arg1 = (aName *) 0 ;
...
新方法会生成一些每个结构的代码,例如:
SWIGCLASS_STATIC int _wrap_aName_set(pTHX_ SV* sv, MAGIC * SWIGUNUSEDPARM(mg))
MAGIC_PPERL
我的PACK()
(在 SWIG 中应该是无操作的)为什么要这样做?
【问题讨论】:
【参考方案1】:谷歌搜索“cpp 标准可变参数宏”会导致 http://en.wikipedia.org/wiki/Variadic_macro 注意到 ...
的扩展是 __VA_ARGS__
,而不是 VA_ARGS
(正如我在某处发现的那样)。当我将宏定义更改为:
#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
它有效。
【讨论】:
以上是关于为啥 Perl 对跨平台打包结构的访问不适用于 SWIG?的主要内容,如果未能解决你的问题,请参考以下文章
为啥“位置:粘性”不适用于 Core UI Bootstrap CSS