All the stuff you define in Buildgrating goes out of scope when you exit the function. So, when you want to call x.calc, the grating object in C++ has no longer access to the slabs and the materials.
To work around this, store all the stuff you create in a global list:
to_keep = []
def BuildGrating():
..
to_keep.append(GaAs)
...
to_keep.append(slab)
...
etc.
2012-05-10 00:02:11 PDT in CAMFR