The question is in the title. I try to wrap c++ code to python, which has nested structs (struct definitions inside another struct definition), and the inner struct doesn't appear in my python module (albeit I want it to appear).
I consulted the Swig documentation (version 4.3, 6.27 Nested classes), and it says:
If the target language doesn't support nested classes directly, or the support is not implemented in the language module (like for Python currently), then the visible nested classes are moved to the same name space as the containing class (nesting hierarchy is "flattened").
To me this reads as if wrapping a nested struct was possible.
So am I doing something wrong? If so, what do I need to do differently? Or is this expected behaviour?
Does the qualifier "visible" play a role here? If so, what do I have to do to make the inner struct visible?
For you to test, I have made a minimal (non)working example:
My File: "test-Swig.h"
struct TestA {
double memberA1;
double memberA2;
struct TestB {
double memberB1;
double memberB2;
};
};
struct TestC {
double memberC1;
double memberC2;
};
and my interface file looks like so:
%module test
%{
#include "test-Swig.h"
%}
%include "test-Swig.h"
From what I have read in the documentation, I would expect to have access to TestA, TestB and TestC, who all appear in the same scope in python. Instead, TestA and TestC appear and can be used, but TestB is absent.
The resulting test.py file that is created by Swig does contain classes A and C, but it doesn't contain class B.
A minimal python code trying to use class B like this:
from build import test
test_class_b = test.TestB()
yields an error:
E AttributeError: module 'build.test' has no attribute 'TestB'. Did you mean: 'TestA'?
If SWIG uses "C" mode to generate source TestB
is wrapped, e.g. swig -python test-Swig.i
.
If SWIG uses "C++" mode to generate source TestB
is missing, but adding %feature("flatnested");
to the .i file enables generation of TestB
. Without the feature, swig -python -c++ test-Swig.i
generates a warning:
Warning 325: Nested struct not currently supported (TestB ignored)
The "flatnested" feature is mentioned in 6.27 Nested classes but only refers to needing it for C# and Java. Clearly that's not the case.
There is also a comment in a C++ example in 6.18.8 More on templates that implies any target language that doesn't support nested classes should use this feature.
// Don't forget to use %feature("flatnested") for OuterClass::InnerStruct and
// OuterClass::InnerClass if the target language doesn't support nested classes.
Here is a standalone test.i
file to demonstrate:
%module test
//%feature("flatnested");
%inline %{
struct TestA {
double memberA1;
double memberA2;
struct TestB {
double memberB1;
double memberB2;
};
};
struct TestC {
double memberC1;
double memberC2;
};
%}
swig -python test.i
(no warning, TestB
generated)
swig -python -c++ test.i
(warning)
test.i(11) : Warning 325: Nested struct not currently supported (TestB ignored)
swig -python -c++ test.i
(%feature above uncommented, no warning, TestB
generated)