Не удается включить <endian.h> при создании привязок SWIG - PullRequest
0 голосов
/ 30 мая 2019

Вот мой раздел препроцессора в моем коде 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 # ошибка «Порядок байтов не определен». Используйте -cpperraswarn возможность продолжить обработку пика.

Кажется, когда SWIG пытается сгенерировать привязки, <machine/endian.h> по некоторым причинам не включается.

Как я могу исправить эту ошибку? Нужно ли что-нибудь добавить в файл интерфейса SWIG?

Я использую macOS 10.14.4.


ДОБАВЛЕНО : Вот как выглядит мой файл интерфейса 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)

1 Ответ

1 голос
/ 02 июня 2019

Причина, по которой SWIG не работает, заключается в том, что он обычно не рекурсирует во включаемые файлы, когда вы %include файл оборачиваете его интерфейс, поэтому определения, определенные в <machine/endian.h>, не обрабатываются.

ТамЕсть несколько вариантов, чтобы исправить это:

  1. Используйте -cpperraswarn и игнорируйте ошибку, как предложено.SWIG обрабатывает #if неправильно, но компилятор значения .SWIG по-прежнему будет выставлять значения HIOFFSET и LOWOFFSET в оболочке, и это значение будет правильным.

  2. %include <machine/endian.h> в явном виде.Это может или не может работать правильно, в зависимости от содержимого файла, и может предоставить больше переменных в оболочке SWIG, чем предполагалось.

  3. Использование -includeall с SWIG для явной рекурсии во все#include файлы.Обычно это не требуется, поскольку SWIG попытается обернуть все определения.Например, вы получите все в #include <stdio.h>, если оно есть.

  4. Явно определите BYTE_ORDER и / или LITTLE_ENDIAN в SWI-файле .i, чтобы обойти проблему.

Вот несколько примеров:

- cpperraswarn Решение:

test.i

%module test

%{
#include "test.h"
%}

%include "test.h"

SWIG генерируетwraning, и в результате определены только HIOFFSET и LOWOFFSET, но они верны для моей машины с прямым порядком байтов даже при ошибке 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_ORDER и LITTLE_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
...