Home > Enterprise >  Accessing C nested structs in Python after interfacing with SWIG
Accessing C nested structs in Python after interfacing with SWIG

Time:12-08

Preface:

I have two header files: "Sample.h" and "Sample2.h". Here are the contents of the two headers:

  1. "Sample.h" has:
#include "Sample2.h"

typedef struct {
    int c;
    sJustFloats sJf;
}sTest;
  1. "Sample2.h" has:
typedef struct {
    float a;
    float b;
}sJustFloats;
  1. Sample.c just has:
#include "Sample.h"
  1. My SWIG interface file has:
%module Sample
%{
/* Put header files here or function declarations like below */
#include "Sample.h"
%}
%include "Sample.h"

%apply float {float a}; // For sJustFloats.a
%apply float {float b}; // For sJustFloats.b
%apply int {int c};     // For sTest.c
%apply sJustFloats {sJustFloats sJf}; // For sTest.sJf
%apply sTest {sTest test}; //I guess this exposes test struct itself.
  1. Steps followed to get .so file that is imported in Python:
gcc -c -fPIC Sample.c Sample_wrap.c -I /usr/include/python3.6m
ld -shared Sample.o Sample_wrap.o -o _Sample.so

Observations:

I am able to import this as a module in Python and I can access fields of sTest as follows:

test = Sample.sTest()
test.c // To access "c" -- This works fine

Problem: I am not able to access fields of struct sJustFloats

If I do test.sJf(), it gives me TypeError: 'SwigPyObject' object is not callable. Similarly test.sJf.a gives: AttributeError: 'SwigPyObject' object has no attribute 'a'

Can someone please tell me how to access members of the struct, sJustFloats?

Additional observations:

  • When I do type(Sample.sTest), it gives me <class 'type'>, whereas doing type(Sample.sTest.sJf) gives me <class 'property'>.
  • If I have both structs in the same file "Sample.h", I am able to access all the fields by doing:
test = Sample.sTest()
sjf = test.sJf()
sjf.a # Works fine
sjf.b # Works fine

Am I missing something in the interface file? Are there are nuances of SWIG that I'm unaware of?

CodePudding user response:

SWIG doesn’t recurse by default, but you need %include "Sample2.h" after %include "Sample.h" and don’t need any of the %apply:

%module Sample

%{
#include "Sample.h"
%}

%include "Sample.h"
%include "Sample2.h"
  • Related