生成SWIG绑定时不能包含<endian.h>

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (1)
  • 关注 (0)
  • 查看 (37)

这是我的C ++代码中的预处理器部分,我想生成SWIG绑定。

#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__FreeBSD_kernel__) \
|| defined(__OpenBSD__)
#include <machine/endian.h>
#endif

#if defined(__linux__) || defined(__CYGWIN__) || defined(__GNU__) || \
defined(ANDROID)
#include <endian.h>
#endif

#ifdef __MINGW32__
#include <sys/param.h>
#endif

#ifdef _MSC_VER
/* _MSVC lacks BYTE_ORDER and LITTLE_ENDIAN */
#define LITTLE_ENDIAN 0x0001
#define BYTE_ORDER LITTLE_ENDIAN
#endif

#if !defined(BYTE_ORDER) || !defined(LITTLE_ENDIAN)
#error No byte order defined
#endif

#if BYTE_ORDER == LITTLE_ENDIAN
# define HIOFFSET 1
# define LOWOFFSET 0
#else
# define HIOFFSET 0    /* word offset to find MSB */
# define LOWOFFSET 1    /* word offset to find LSB */
#endif

但是当我尝试使用该swig命令生成SWIG绑定时,我收到以下错误:

错误:CPP #error“未定义字节顺序”。使用-cpperraswarn选项继续swig处理。

当SWIG尝试生成绑定时,似乎<machine/endian.h>由于某些原因而未包含。

我该如何解决这个错误?我是否需要向SWIG接口文件添加任何内容?

我正在使用macOS 10.14.4。

ADDED:这是我的SWIG界面文件的样子。

%module pd
%{
    #include "myBindings.h"
%}
%include "myBindings.h"

正如你所看到的,它并没有什么特别之处。

我使用以下命令生成绑定:

swig -c++ -lua -fcompact -fvirtual -I../../../libs/openFrameworks myBindings.i && mv myBindings_wrap.cxx myBindings.cpp

然后我得到上面提到的错误。即使我离开#include <machine/endian.h>它仍然会产生相同的错误。(No byte order defined

提问于
用户回答回答于

SWIG失败的原因是,当您%include打包其接口的文件时,它通常不会递归到包含文件中,因此<machine/endian.h>不会处理定义的定义。

有许多方法可以解决这个问题:

  1. -cpperraswarn根据建议使用并忽略错误。SWIG将错误地处理#if,但它是构建值的编译器。SWIG仍然会在包装器中公开HIOFFSETLOWOFFSET值,并且值将是正确的。
  2. %include <machine/endian.h>明确。根据文件的内容,这可能会或可能不会正常工作,并且可能会在SWIG包装器中暴露比预期更多的变量。
  3. -includeall与SWIG一起使用以明确递归到所有#include文件。这通常不需要,因为SWIG将尝试包装所有定义。例如,#include <stdio.h>如果存在,您将获得所有内容。
  4. 明确定义BYTE_ORDER和/或LITTLE_ENDIAN在SWIG .i文件中解决此问题。

这里有几个例子:

--cpperraswarn解决方案:

test.i

%module test

%{
#include "test.h"
%}

%include "test.h"

SWIG生成wraning,结果只有HIOFFSETLOWOFFSET定义,但它们对于我的小端机正确的,即使从SWIG错误。编译器仍然正确处理定义。

>>> import test
>>> dir(test)
['HIOFFSET', 'LOWOFFSET', 'SWIG_PyInstanceMethod_New', '__builtin__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_swig_getattr', '_swig_property', '_swig_repr', '_swig_setattr', '_swig_setattr_nondynamic', '_swig_setattr_nondynamic_method', '_test']
>>> test.HIOFFSET
1

%include endian.h解决方案:

在这种情况下,我有一台Windows机器,所以我通过创建一个msvc_endian.h文件BYTE_ORDERLITTLE_ENDIAN在其中定义来模拟问题。

test.h被修改为使用以下代码段:

#ifdef _MSC_VER
#include "msvc_endian.h"
#endif

test.i显式处理了标题:

%module test

%{
#include "test.h"
%}

%include "msvc_endian.h"
%include "test.h"

msvc_endian.h

#define LITTLE_ENDIAN 0x0001
#define BYTE_ORDER LITTLE_ENDIAN

SWIG现在没有警告,结果仍然正确,但是由于处理了子标题,LITTLE_ENDIAN并且BYTE_ORDER在包装器中也显示为值:

>>> import test
>>> dir(test)
['BYTE_ORDER', 'HIOFFSET', 'LITTLE_ENDIAN', 'LOWOFFSET', 'SWIG_PyInstanceMethod_New', '__builtin__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_swig_getattr', '_swig_property', '_swig_repr', '_swig_setattr', '_swig_setattr_nondynamic', '_swig_setattr_nondynamic_method', '_test']
>>> test.HIOFFSET
1

扫码关注云+社区

领取腾讯云代金券