Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Preprocessor macro in SWIG

Tags:

python

c

swig

I'm trying to get SWIG to recognize a simple preprocessor macro that "defines" a new function based on another definition and more complicated function. So, in the C header file I have:

#define FOO 1
#define my_macro_fun(args) my_fun(args,FOO)

SWIG sees and successfully wraps my_fun, but I want it to wrap my_macro_fun instead.

like image 510
johntfoster Avatar asked Jul 09 '12 21:07

johntfoster


People also ask

What is macro processing in preprocessor?

Macros allow you to write commonly used PL/I code in a way that hides implementation details and the data that is manipulated and exposes only the operations. In contrast with a generalized subroutine, macros allow generation of only the code that is needed for each individual use.

What is macro in preprocessor directives?

A macro is a fragment of code that is given a name. You can define a macro in C using the #define preprocessor directive. Here's an example. #define c 299792458 // speed of light. Here, when we use c in our program, it is replaced with 299792458 .

What is difference between macros and preprocessor directives in C?

macros are name for fragment of code. A macro processor is a program that copies a stream of text from one place to another, making a systematic set of replacements as it does so. ... A preprocessor is a program that processes its input data to produce output that is used as input to another program.

How do I create a swig interface file?

The most common format of a SWIG interface is as follows: %module mymodule %{ #include "myheader. h" %} // Now list ANSI C/C++ declarations int foo; int bar(int x); ... The module name is supplied using the special %module directive.


1 Answers

SWIG tries to spot macros that are constants and wrap them, but it won't be able to do anything smart with a macro like that. Fortunately there's an easy work around. Imagine you have the following header file:

#define FOO 1
#define my_macro_fun(args) my_fun(args,FOO)

void my_fun(int a, int b);

You can wrap it like:

%module test
%{
#include "test.h"
%}

%include "test.h"

which skips the my_macro_fun function. To get SWIG to wrap that though all you need to do is:

%module test
%{
#include "test.h"
%}

// Lie! Tell SWIG that it should be wrapped like any other function.
void my_macro_fun(int);

// This is entirely optional: it will cause my_fun to be wrapped as well
%include "test.h"

This little lie is perfectly fine in SWIG - it'll generate Wrapper code that assumes my_macro_fun(int) is callable, exactly like you would if you were using the macro. When compiling the wrapper the compiler will end up using the macro there and nobody is any the wiser.

Note that the order is important - the function that's really a macro needs to come before the %include in the interface file otherwise SWIG will try to expand the macro during the parsing of your declaration which makes for a syntax error. You can skip the %include entirely, or use a %ignore as well if you want to include it for other parts but suppress the original my_fun in the generated interface.


With some SWIG languages (e.g. Python) you can also use the typemap default:

%module test
%{
#include "test.h"
%}

%typemap(default) int b {
  $1 = FOO;
}

%include "test.h"

To supply a value for an argument if none is given for it.

like image 152
Flexo Avatar answered Oct 20 '22 00:10

Flexo