#c #swig
Вопрос:
Допустим, у меня в коде на C есть следующий макрос:
#if __SOME_CONDITION__
#define SAMPLE_TYPE double
#elif
#define SAMPLE_TYPE float
#endif
который в основном определяет SAMPLE_TYPE
один из двух возможных типов примитивов в зависимости от другой директивы компилятора/другого определения препроцессора.
У меня есть следующий заголовок для класса, который я обертываю с помощью SWIG:
class SomethingStatic {
public:
static SAMPLE_TYPE someFunction();
}
когда я создаю и обертываю код и ссылку SomethingStatic.someFunction
из своего кода Java, тип возвращаемого значения задается как SWIGTYPE_p_SAMPLE_TYPE
, который также был сгенерирован SWIG.
Как я могу настроить SWIG для возврата примитива float
или double
значения, которое оценивает макрос?
Комментарии:
1. Я не знаю, сработает ли это, но SWIG мог бы понять, что вы делаете лучше, если бы вы использовали typedefs вместо #defines.
2. @zwol, к сожалению, он обеспечивает то же поведение, что и typedef.
3. Предварительно обработайте код, прежде чем позволить SWIG его увидеть? Возможно, не лучший способ, но это то, что сразу приходит на ум.
4. Прошло довольно много времени с тех пор, как я использовал
#define
илиtypedef
для обработки примитивных типов. Сегодня я использую шаблоны, и здесь SWIG всегда обрабатывает их правильно. Недостатком является то, что вам необходимо явно создавать экземпляры ваших шаблонов, используя%template
синтаксис5. Это должно сработать нормально. Убедитесь, что заголовок определения SAMPLE_TYPE непосредственно
%include
отредактирован в.i
файле. По умолчанию SWIG не рекурсирует в файлы заголовков.
Ответ №1:
SWIG понимает препроцессор, но вы должны %include
использовать заголовок с прямым определением. SWIG не рекурсирует в другие заголовки, включенные в заголовок. Также не забудьте объявить значения препроцессора при вызове swig
, а также компилятора.
Пример:
состояние.h
#ifdef CONDITION
#define SAMPLE_TYPE double
#else
#define SAMPLE_TYPE int
#endif
класс.h
#include "condition.h"
class SomethingStatic {
public:
static SAMPLE_TYPE someFunction() {
#ifdef CONDITION
return 1.5;
#else
return 2;
#endif
}
};
test.i
%module test
// This code is directly included in the wrapper.
// C will process condition.h implicitly
%{
#include "class.h"
%}
// Headers that SWIG will create wrappers for.
// SWIG *does not* recurse into subheaders by default.
%include "condition.h" // must be explicit with SWIG
%include "class.h"
%}
Использование «swig -python -c test.i» и компиляция без /DCONDITION:
>>> import test
>>> x=test.SomethingStatic()
>>> x.someFunction()
2
Использование «swig -DCONDITION -python -c test.i» и компиляция с /DCONDITION:
>>> import test
>>> x=test.SomethingStatic()
>>> x.someFunction()
1.5
Демонстрация, если вы закомментируете %include "condition.h"
строку, которая, по-видимому, является первоначальной проблемой операции:
>>> import test
>>> x=test.SomethingStatic()
>>> x.someFunction()
<Swig Object of type 'SAMPLE_TYPE *' at 0x000001D369F9B4E0>
Комментарии:
1. Вот и все! Указав заголовок в разделе %include файла интерфейса, я заставил его работать должным образом. Оглядываясь назад, это имеет смысл, но я совершенно упустил из виду, что определения находились внутри файла, на который ссылались только в коде C, а не через SWIG. Спасибо!