Interrogate Hello World troubles

Hello, panda3d forums!

I’m having some trouble using interrogate to generate a simple HelloWorld module. I’m mostly trying to follow the tutorial from panda3d.org/manual/index.php/Interrogate. Here is my header file:

// test.h
#ifndef INTERROGATE_TEST_H
#define INTERROGATE_TEST_H

class HelloWorld
{
public:
        char const *greet();
};

#endif

And my cxx file:

// test.cxx
#include "test.h"
char const *HelloWorld::greet()
{
        return "Hello, World!";
}

It’s the simplest class I could come up with. Using interrogate, I ran the following commands:

$ interrogate -oc test_igate.cxx -od test.in -python-native test.h
$ interrogate_module -oc test_module.cxx -python-native test.in

These ran fine without any error. I compiled and linked the resulting source files using the instructions from ( panda3d.org/manual/index.php/How_t … e_on_Linux ):

$ g++ -c *.cxx -I/usr/include/python2.5 -I/usr/include/panda3d
$ g++ *.o -o test.so -fPIC -L/usr/lib/panda3d -lp3framework -lpanda -lpandafx -lpandaexpress -lp3dtoolconfig -lp3dtool -lp3pystub -lp3direct -shared

This seems to go alright, and I get a test.so file in that directory. Then I try to run python and import my new class:

Python 2.5.2 (r252:60911, Oct  5 2008, 19:24:49) 
[GCC 4.3.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from test import HelloWorld
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: dynamic module does not define init function (inittest)
>>>

Any idea what’s going on? Am I missing something?

Hmm, well, one problem is that you have no PUBLISHED methods defined in your class (your only method is just declared public, not PUBLISHED, so interrogate won’t see it).

In order to define the PUBLISHED macro properly, you will need to include at least dtoolbase.h, which might in turn have other requirements. The generated interrogate file will require including this file, too.

Another problerm is that you need to specify “-library test” on the interrogate_module command line, to tell it the name of the library you are generating.

David

I tried your suggestions but it didn’t make a difference. I did notice a footnote on ( panda3d.org/manual/index.php/Interrogate ). In the panda3d source, there are skeleton classes that I should use to help me learn interrogate. After downloading the source, I tried following the instructions on the interrogate manual. I couldn’t get past the first step:

~/panda3d-1.5.4/panda/src/skel$ interrogate -oc basicSkel.cxx -od basicSkel.in -python-native basicSkel.h
    *** Error in basicSkel.I near line 22, column 13:
    syntax error, unexpected IDENTIFIER, expecting '{' or ';' or ':' or '='
Error parsing file: 'basicSkel.h'

This is unmodified code from the website. Am I missing something here?

Try -python instead of -python-native.

Probably not what you want, because in -python mode, C++ objects and methods will be converted into an object handle and a list of independent Python functions (just like C) instead of being converted into true Python objects.

So the fundamental problem here is that interrogate has been tightly developed in conjunction with Panda, and it is primarily designed to be used within the existing Panda build environment. It should theoretically be possible to use it outside of Panda’s build environment, but you will have to learn the exact combination of parameters and header files etc. that it will require.

The easiest way to learn this is to start within Panda’s build environment in the first place. Interrogate works fine there. If that works to your satisfaction, you might as well stay there. Or, if you really want to be completely isolated from Panda’s build environment, at least you will be empowered to figure out how to make that happen.

The skel directory that you refer to is built automatically by both the makepanda and ppremake build systems. Try building it with one of those, and you’ll see the proper command lines that are passed to interrogate and interrogate_module.

David

I ran into the same issue with the ‘init’ and i followed David’s reply of using Published and -library and it imports the pyd file properly.

Though I did run into an error with trying to import the class.
For example:
using the BasicSkel example and assuming my pyd file was WrapperTry,

I am able to do from WrapperTry import * but for some reason it isnt allowing me to do from WrapperTry import BasicSkel.

Error: ImportError: cannot import name BasicSkel

Could someone help with this?

Also, For anyone interested, in the BasicSkel example, if you comment out the .I include the project builds fine.
[/i]

Have you tried my suggestion of examining the exact commands generated by makepanda or ppremake to run interrogate for basicSkel? For instance, I think you’re missing a separate call to interrogate_module, which generates the part of the code wrappers that makes your .pyd importable to Python.

I don’t understand what you mean by this:

That sounds like trouble–without the .I file, you’ll have no function body for the inline methods. How can it possibly build without that? And are you saying that the project doesn’t build if you leave it in? Why not, what is the error message? (You haven’t attempted to add the .I file to your project, have you? That would be a mistake.)

David

Your right. If you add the .I file it builds fine. I thought it didn’t exist earlier and so thought it wasn’t required.

But I still am not able to solve the problem of:

Also,

I didn’t understand what you meant by this clearly. I went through the documentation of makepanda and ppremake and am still confused about how to use it. Should i use makepanda - everything and look at a log file?
[/quote]

Here’s makepanda’s build log for the skel directory:

g++ -ftemplate-depth-30 -fPIC -c -o built/tmp/skel_composite.o -I"/usr/include/python2.6" -I"built/tmp" -I"built/include" -Ipanda/src/skel -O2 -DBUILDING_PANDASKEL "panda/src/skel/skel_composite.cxx"

built/bin/interrogate -srcdir panda/src/skel -Ipanda/src/skel -Dvolatile -Dmutable -DCPPPARSER -D__STDC__=1 -D__cplusplus -D__inline -D__const=const -D_LP64 -DFORCE_INLINING -oc built/tmp/libskel_igate.cxx -od built/pandac/input/libskel.in -fnames -string -refcount -assert -python-native -Sbuilt/include/parser-inc -I"panda/src/skel" -S"/usr/include/python2.6" -S"built/tmp" -S"built/include" -DBUILDING_PANDASKEL -module pandaskel -library libskel "basicSkel.h" "config_skel.h" "skel_composite.cxx" "typedSkel.h" "basicSkel.h" "config_skel.h" "skel_composite.cxx" "typedSkel.h"

g++ -ftemplate-depth-30 -fPIC -c -o built/tmp/libskel_igate.o -I"/usr/include/python2.6" -I"built/tmp" -I"built/include" -Ipanda/src/skel -O2 -DBUILDING_PANDASKEL "built/tmp/libskel_igate.cxx"

It looks hairy, but I hope it helps you somehow.

I tried to use similar commands on interrogate to build it but it still couldn’t get: from libBasicSkel import BasicSkel to work. I wonder if there is another way to do it.

We are actually looking for a way to include these third party AI libraries (written in C++) into the Panda python framework. So is rebuilding the version of Panda with these dlls the only way to go about it? I looked through the video tutorial too but that’s only got me this far.

Here are the steps i followed:

b[/b] interrogate -D__inline -DCPPPARSER -D__cplusplus -S/use/include/panda3d/parser-inc -S/usr/include/ - I/usr/include/panda3d/ -oc wrapper.cxx -od wrapper.in -fnames -string -refcount -assert -python-native -module BasicSkel -library libBasicSkel BasicSkel.h

b[/b] interrogate_module -oc wrapper_module.cxx -module BasicSkel -library libBasicSkel -python-native wrapper.in

b[/b] This created wrapper.cxx and wrapper_module.cxx. I compiled them and created the object files which I included in my Visual Studio linker and include directory (both, since I wasn’t sure where to put it exactly to include it).

b[/b] Then I made the dll and lib files by building it with changes in the configuration properties in Visual Studio.

b[/b] I took this dll and lib file and pasted them in my python project directory. I renamed the dll to pyd. I also had to rename the dll and lib files from (WrapperTry.dll and WrapperTry.lib) to (libBasicSkel.pyd and libBasicSkel.lib) since I was getting the init error mentioned eariler in the post. (This seemed to solve it…I tried this as in wrapper.cxx I found an initlibSkel() created so I assumed that python references it from the filename?)

Now when I do: from libBasicSkel import BasicSkel it gives the error saying

ImportError: cannot import name BasicSkel

Have i missed any critical steps or is there an alternate route I should take to get this to work ?

I don’t know - can you try doing this?

import libBasicSkel
print dir(libBasicSkel)

Also are you sure the class has “INLINE” methods (and that it’s including one of the Panda headers so that you make sure INLINE is even defined)? You could also try putting interrogate in promiscuous mode.

That sounds generally right. You are correct that Python determines the name of the init function based on the filename. Note also that that .lib file is not required for Python.

What symbols do you have in libBasicSkel?

import libBasicSkel
dir(libBasicSkel)

In your generated wrapper.cxx file, do you have code that looks vaguely like this?

//********************************************************************
//*** Py Init Code For .. BasicSkel | BasicSkel
//********************************************************************
PyMethodDef Dtool_Methods_BasicSkel[]= {
  { "setValue",(PyCFunction ) &Dtool_BasicSkel_set_value_4, METH_VARARGS| METH_K
EYWORDS, (char *)Dtool_BasicSkel_set_value_4_comment},
  { "getValue",(PyCFunction ) &Dtool_BasicSkel_get_value_5, METH_VARARGS| METH_K
EYWORDS, (char *)Dtool_BasicSkel_get_value_5_comment},
  { "setValueAlt",(PyCFunction ) &Dtool_BasicSkel_set_value_alt_6, METH_VARARGS|
 METH_KEYWORDS, (char *)Dtool_BasicSkel_set_value_alt_6_comment},
  { "getValueAlt",(PyCFunction ) &Dtool_BasicSkel_get_value_alt_7, METH_VARARGS|
 METH_KEYWORDS, (char *)Dtool_BasicSkel_get_value_alt_7_comment},
  { NULL, NULL }
};

David

Output is a one line print statement:

[‘Dtool_PyNavtiveInterface’, ‘doc’, ‘file’, ‘name’]

Also, for the wrapper.cxx:


static PyMethodDef python_simple_funcs[] = {
  //Support Function For Dtool_types ... for now in each module ??
  {"Dtool_BorrowThisReference", &Dtool_BorrowThisReference,METH_VARARGS,"Used to borrow 'this' poiner ( to, from)\n Assumes no ownership"}, 
  {"Dtool_AddToDictionary", &Dtool_AddToDictionary,METH_VARARGS,"Used to Items Into a types (tp_dict)"}, 
  { NULL, NULL ,0,NULL}
};

struct LibrayDef libBasicSkel_moddef = {python_simple_funcs,BuildInstants};
static InterrogateModuleDef _in_module_def = {
  1251480401,  /* file_identifier */
  "libBasicSkel",  /* library_name */
  "qgd5",  /* library_hash_name */
  "BasicSkel",  /* module_name */
  "wrapper.in",  /* database_filename */
  (InterrogateUniqueNameDef *)0,  /* unique_names */
  0,  /* num_unique_names */
  (void **)0,  /* fptrs */
  0,  /* num_fptrs */
  1,  /* first_index */
  1  /* next_index */
};

Configure(_in_configure_libBasicSkel);
ConfigureFn(_in_configure_libBasicSkel) {
  interrogate_request_module(&_in_module_def);
}

That’s not the part of wrapper.cxx I was looking for; I was looking for the part that defines the BasicSkel method, or any part of the BasicSkel class. If that part is missing, then it looks like interrogate has run successfully, but did not decide to generate wrappers for your BasicSkel class.

Are you using the standard basicSkel.h file from the distribution? Note that you misspelled the filename on the command line; you wrote “BasicSkel.h” instead of “basicSkel.h”, though I don’t think this matters.

You shouldn’t have /usr/include on the interrogate command line. That’s asking for trouble.

Your interrogate command line works fine for me (with some modifications for my local path settings) when run on the standard basicSkel.h file, so there must be something else in your environment or something that’s wrong. You can put -v on the interrogate command line; that might give some more insight. When I do this, I get:

fisheye:~/player/panda/src/skel> interrogate -v -D__inline -DCPPPARSER -D__cplusplus -S $DTOOL/built/include/parser-inc -I $DTOOL/built/include -I $PANDA/built/include -oc wrapper.cxx -od wrapper.in -fnames -string -refcount -assert -python-native -module BasicSkel -library libBasicSkel BasicSkel.h

Reading BasicSkel.h
  Reading /home/drose/player/panda/built/include/pandabase.h
    Reading /home/drose/player/dtool/built/include/dtoolbase.h
      Reading /home/drose/player/dtool/built/include/dtool_config.h
      Reading /home/drose/player/dtool/built/include/dtoolsymbols.h
      *** Warning in /home/drose/player/dtool/built/include/dtoolbase.h near line 100, column 2:
      Cannot find assert.h
      *** Warning in /home/drose/player/dtool/built/include/dtoolbase.h near line 114, column 2:
      Cannot find sys/types.h
      Reading /home/drose/player/dtool/built/include/parser-inc/malloc.h
      *** Warning in /home/drose/player/dtool/built/include/dtoolbase.h near line 134, column 2:
      Cannot find io.h
      *** Warning in /home/drose/player/dtool/built/include/dtoolbase.h near line 142, column 2:
      Cannot find string.h
      *** Warning in /home/drose/player/dtool/built/include/dtoolbase.h near line 154, column 2:
      Cannot find minmax.h
      Reading /home/drose/player/dtool/built/include/parser-inc/stdtypedefs.h
      Reading /home/drose/player/dtool/built/include/dtoolbase_cc.h
        Reading /home/drose/player/dtool/built/include/parser-inc/iostream
        Reading /home/drose/player/dtool/built/include/parser-inc/string
          Reading /home/drose/player/dtool/built/include/parser-inc/stdtypedefs.h
    Reading /home/drose/player/panda/built/include/pandasymbols.h
  Reading basicSkel.I

The warnings about missing system header files is normal.

David

Your right, I had misspelled it but it luckily it didn’t give any errors.

Now, I am a bit confused about which folders these are since I am using the Windows environment and the 1.6.2 SDK download.

$DTOOL/built/include/parser-inc
$DTOOL/built/include/
$PANDA/built/include/

Is this the same as :

C:\Panda3D-1.6.2\include\parser-inc
C:\Panda3D-1.6.2\include

Also, I don’t know if this is helpful now but I ran this:

interrogate -v -D__inline -DCPPARSER -D__cplusplus -I C:\Panda3D-1.6.2\include -oc wrapper.cxx -od wrapper.in -fnames -string -refcount -assert -python-native -module BasicSkel -library libBasicSkel basicSkel.h

*Note: I also tried including C:\Panda3D-1.6.2\include\parser-inc with the same output.

Output:

[b]
The same output as yours all the way till the end where i get:

 Attempt to use undefined namespace: std
 Error in dtoolbase_cc.h ( line 103 )

 Symbol ios is not a known scope in
 Error in dtoolbase_cc.h ( line 103 )

 parse error
 Error parsing file: 'basicSkel.h'

[/b]

I didn’t mean to confuse you. My own build environment is very different from the standard 1.6.2 SDK environment. Pay no attention to my variables named $DTOOL and $PANDA and such; that’s particular to my own environment. But, yeah, those are roughly equivalent to C:\Panda3D-1.6.2 .

Looks like you’ve got another typo on your interrogate line: you said “-DCPPARSER” instead of “-DCPPPARSER”.

David

Oops. Sorry. Fixed that.

Okay, so I think now we have some progress.

I have the same output as what you have now. I had to include basicSkel.I in the C:\Panda3D-1.6.2\bin folder too which fixed a missing file error.

Well, does it import now?

David

There seems to be some linking errors when I am trying to create the dll file in Visual Studio:

Creating library C:\navin\C++ panda projects\WrapperTry\Release\WrapperTry.lib and object C:\navin\C++ panda projects\WrapperTry\Release\WrapperTry.exp
1>wrapper.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) void __cdecl RegisterRuntimeClass(struct Dtool_PyTypedObject *,int)" (__imp_?RegisterRuntimeClass@@YAXPAUDtool_PyTypedObject@@H@Z)
1>wrapper.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) struct _object * __cdecl Dtool_BorrowThisReference(struct _object *,struct _object *)" (__imp_?Dtool_BorrowThisReference@@YAPAU_object@@PAU1@0@Z)
1>wrapper.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) int __cdecl DTool_PyInit_Finalize(struct _object *,void *,struct Dtool_PyTypedObject *,bool,bool)" (__imp_?DTool_PyInit_Finalize@@YAHPAU_object@@PAXPAUDtool_PyTypedObject@@_N3@Z)
1>wrapper.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) struct Dtool_PyTypedObject Dtool_DTOOL_SUPPER_BASE" (__imp_?Dtool_DTOOL_SUPPER_BASE@@3UDtool_PyTypedObject@@A)
1>wrapper.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) void __cdecl DTOOL_Call_ExtractThisPointerForType(struct _object *,struct Dtool_PyTypedObject *,void * *)" (__imp_?DTOOL_Call_ExtractThisPointerForType@@YAXPAU_object@@PAUDtool_PyTypedObject@@PAPAX@Z)
1>wrapper.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) struct _object * __cdecl Dtool_AddToDictionary(struct _object *,struct _object *)" (__imp_?Dtool_AddToDictionary@@YAPAU_object@@PAU1@0@Z)
1>wrapper.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: static class Notify * __cdecl Notify::ptr(void)" (__imp_?ptr@Notify@@SAPAV1@XZ)
1>wrapper.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: void __thiscall Notify::clear_assert_failed(void)" (__imp_?clear_assert_failed@Notify@@QAEXXZ)
1>wrapper.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const & __thiscall Notify::get_assert_error_message(void)const " (__imp_?get_assert_error_message@Notify@@QBEABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ)
1>wrapper.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: bool __thiscall Notify::has_assert_failed(void)const " (__imp_?has_assert_failed@Notify@@QBE_NXZ)
1>wrapper.obj : error LNK2001: unresolved external symbol __imp__interrogate_request_module
1>wrapper.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) struct PyMemberDef * standard_type_members" (__imp_?standard_type_members@@3PAUPyMemberDef@@A)
1>wrapper.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: int __thiscall BasicSkel::get_value(void)" (__imp_?get_value@BasicSkel@@QAEHXZ)
1>wrapper.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: void __thiscall BasicSkel::set_value(int)" (__imp_?set_value@BasicSkel@@QAEXH@Z)
1>wrapper.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: __thiscall BasicSkel::~BasicSkel(void)" (__imp_??1BasicSkel@@QAE@XZ)
1>wrapper.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: __thiscall BasicSkel::BasicSkel(void)" (__imp_??0BasicSkel@@QAE@XZ)
1>wrapper_module.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) void __cdecl Dtool_PyModuleInitHelper(struct LibrayDef * * const,char const *)" (__imp_?Dtool_PyModuleInitHelper@@YAXQAPAULibrayDef@@PBD@Z)
1>C:\navin\C++ panda projects\WrapperTry\Release\WrapperTry.dll : fatal error LNK1120: 17 unresolved externals