Building code outside source dir: undefined symbol: Dtool_Ga

Hi,

I’ve been trying to create my own non-linear Lens. As a starting point, I copied fisheyeLens.{cxx,h,I} to a directory outside the project source directory.
I renamed “[Ff]isheye” to “[Pp]hisheye” and shouted:

interrogate -DCPPPARSER -Dvolatile= -D__cplusplus -S/usr/include/panda3d/parser-inc/ -I/usr/include/panda3d/ -oc phisheyeLens_igate.cxx -od phisheyeLens.in -fnames -string -refcount -assert -python-native phisheyeLens.h -python -module libPhisheyeLens -library libPhisheyeLens -python

interrogate_module -oc phisheyeLens_module.cxx -module libPhisheyeLens -library libPhisheyeLens -python phisheyeLens.in

g++ phisheyeLens.cxx phisheyeLens_igate.cxx phisheyeLens_module.cxx -Wall -fPIC -shared -o phisheyeLens.so -I/usr/include/eigen3 -I/usr/include/panda3d/ -I/usr/include/python2.7/ -L/usr/lib64/panda3d /usr/lib64/panda3d/libp3dtool.so /usr/lib64/panda3d/libp3direct.so /usr/lib64/panda3d/libp3dtoolconfig.so /usr/lib64/panda3d/libp3framework.so /usr/lib64/panda3d/libp3pystub.so /usr/lib64/panda3d/libpanda.so /usr/lib64/panda3d/libpandaexpress.so /usr/lib64/panda3d/libpandafx.so /usr/lib64/panda3d/libpandaskel.so -lp3framework -lpanda -lpandafx -lpandaexpress -lp3dtoolconfig -lp3dtool -lp3pystub -lp3direct -lpandaskel

(I know I probably don’t need all the libs, but I thought, better to start with too many than too few.)

The source compiles and everything is well until I try using the thing. In Python, I get:

>>> import phisheyeLens
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: ./phisheyeLens.so: undefined symbol: Dtool_Gay8JGY6

Cluebat?

Thanks,
Johannes

PS: As I said, I didn’t really change the code, just did a copy/replace. Anyway: I’ve posted it on Hastebin, just to make sure:

phisheyeLens.cxx
phisheyeLens.h
phisheyeLens.I

Details:

Panda3D version: 1.8.1, from the latest tarball on the website. Uninstalled Ubuntu package, built from source.
gcc: 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
Python: 2.7.3

I’m not sure what Dtool_Gay8JGY6 is, but I’m guessing it’s the name of a function that was automatically generated by interrogate. Is it defined in the _igate.cxx file? If so, could you paste its definition?

D’uh, I should have grep’d that name. Anyway: it’s only mentioned in the _module.cxx:

...
extern "C" {
...
  PyObject *Dtool_Gay8JGY6(PyObject *self, PyObject *args);
...
}
...
static PyMethodDef python_methods[5] = {
  { "_inPGay8JGY6", &_inPGay8JGY6, METH_VARARGS },
...
};
...

Full code of phisheyeLens_module.cxx, phisheyeLens_igate.cxx at Hastebin.

One problem that immediately jumps out is that you correctly specified -python-native to the interrogate command, but failed to specify it to the interrogate_module command, so the two programs are generating incompatible code. Make sure that you specify the correct command-line parameters to both tools–they are confusingly powerful and many of their features are abandoned or no longer used.

David

Thanks, that did it (almost): I removed the -python' switch from theinterrogate’ command and added -python-native' to theinterrogate_module’ command.
I also had to change the library name from libPhisheyeLens to phisheyeLens so it matched the name of the output file from the compilation command (before that, I got an error saying “dynamic module does not define init function (initphisheyeLens)”).

Now I can compile and import PhisheyeLens', and even use it instead ofFisheyeLens’ in the example code found in this thread. I’m getting a warning, though, wenn `PhisheyeLens’ is imported: “Class PhisheyeLens has a zero TypeHandle value; check that init_type() is called.” Is that something I should worry about?

For reference: this is how I generate the code and compile the module.

  interrogate -DCPPPARSER -Dvolatile= -D__cplusplus -S/usr/include/panda3d/parser-inc/ -I/usr/include/panda3d/ -oc phisheyeLens_igate.cxx -od phisheyeLens.in -fnames -string -refcount -assert -python-native phisheyeLens.h -module phisheyeLens -library phisheyeLens

interrogate_module -oc phisheyeLens_module.cxx -module phisheyeLens -library phisheyeLens -python-native phisheyeLens.in

g++ phisheyeLens.cxx phisheyeLens_igate.cxx phisheyeLens_module.cxx -Wall -fPIC -shared -o phisheyeLens.so -I/usr/include/eigen3 -I/usr/include/panda3d/ -I/usr/include/python2.7/ -L/usr/lib64/panda3d /usr/lib64/panda3d/libp3dtool.so /usr/lib64/panda3d/libp3direct.so /usr/lib64/panda3d/libp3dtoolconfig.so /usr/lib64/panda3d/libp3framework.so /usr/lib64/panda3d/libp3pystub.so /usr/lib64/panda3d/libpanda.so /usr/lib64/panda3d/libpandaexpress.so /usr/lib64/panda3d/libpandafx.so /usr/lib64/panda3d/libpandaskel.so -lp3framework -lpanda -lpandafx -lpandaexpress -lp3dtoolconfig -lp3dtool -lp3pystub -lp3direct -lpandaskel

This means that you did not call init_type() of the class at static init time. See config_distort.cxx. The ConfigureFn macro is used to create a static initialiser that calls init_libdistort when the library is loaded, which calls init_type() on all the typed classes.

That’s it, thanks a lot. I guess I’m done for now.