I have Ubuntu-20.04, Anaconda-3 (installed into the user dir) with Python-3.7.9 and SWIG-4.0.
Here are my files.
a.h
:
void foo(void);
a.c
:
#include <stdio.h>
#include "a.h"
void foo(void) { printf("Foo!\n"); }
a.i
:
%module a
%inline %{
#include "a.h"
%}
test.py
:
import a
a.foo()
Compile script compile.sh
:
A=$HOME/opt/anaconda3
I=$A/include/python3.7m
gcc -c -fpic -DHAVE_CONFIG_H -I$I a.c
$A/bin/swig -python -py3 a.i
gcc -c -fpic -DHAVE_CONFIG_H -I$I a_wrap.c
gcc -shared a.o a_wrap.o -o _a.so
After compilation the test script produces
Traceback (most recent call last):
File "test.py", line 2, in <module>
a.foo()
AttributeError: module 'a' has no attribute 'foo'
However, if I write a longer interface file everything is OK:
%module a
%{
#include "a.h"
%}
%include "a.h"
UPD @Jens suggested to replace #
with %
in the first (short) interface file. In this case I got
a_wrap.c:2701:1: error: expected identifier or '(' before '%' token
2701 | %include "a.h"
| ^
a_wrap.c:2720:12: error: '_wrap_foo' undeclared here (not in a function)
2720 | { "foo", _wrap_foo, METH_NOARGS, NULL},
| ^~~~~~~~~
gcc: error: a_wrap.o: No such file or directory
%inline
both includes the braced code directly in the SWIG-generated wrapper code, but also processes it to generated target language interfaces. So this:
%module a
%inline %{
void foo(void);
%}
is equivalent to:
%module a
%{
void foo(void) {}
%}
void foo(void) {}
But this:
%module a
%inline %{
#include "a.h"
%}
is equivalent to:
%module a
%{
#include "a.h"
%}
#include "a.h" // NOT the same as %include "a.h" and isn't processed for interfaces
To show that %inline
is both included and processed, I made:
%module a
%inline %{
#include "a.h" // ignored in "include-in-wrapper" pass
#ifdef SWIG
%include "a.h" // processed in "wrap-with-SWIG" pass
#endif
%}
The above did the right thing and exposed the interface, but it's worse than just using:
%module a
%{
#include "a.h"
%}
%include "a.h"
%inline
is really for inserting new functions into the wrapper and exposing the interface, such as this:
%module a
%inline %{
class myClass
{
private:
int a;
public:
myClass(){}
void foo(){}
};
%}
where otherwise you'd have to write, at a minimum:
%module a
%{ // new functionality added to wrapper
class myClass
{
private:
int a;
public:
myClass(){}
void foo(){}
};
%}
class myClass // process the interface
{
public: // note don't need to repeat private part or
myClass(); // implementation, just public declarations to be exposed.
void foo();
};