0

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?

10
  • i dont remember if swig parses includes recursively. Did you try to also #include "Sample2.h" in the interface file? Commented Dec 7, 2022 at 8:24
  • As it turns out, it does. : ) I tried adding #include "Sample2.h" in the interface file, that resulted in a "conflicting types for 'sJustFloats'", "previous declaration here" during compilation with gcc. May be it was not explicit enough in the question, but from Python, I am able to see sJustFloats. sTest has an integer and sJf. It's just that I'm not able to access any of the fields within sJf. Commented Dec 7, 2022 at 8:34
  • 1
    sry I meant %include "Sample2.h" Commented Dec 7, 2022 at 8:41
  • 1
    No, SWIG doesn’t recurse by default, but you need %include "Sample2.h" after %include "Sample.h" and don’t need any of the %apply Commented Dec 7, 2022 at 8:42
  • btw afaik the advantage of swig is that its supports bindings from and to many languages. For only Python calling C there are easier to use alternatives Commented Dec 7, 2022 at 8:43

1 Answer 1

1

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"
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.