[Guide] Interrogate in 8 steps

[size=150]Edit[/size]

Please checkout my module builder at https://discourse.panda3d.org/viewtopic.php?t=18420
which automates the whole process of building a module, including the interrogate step!

Original post:

I’ve spend the last 3 days getting Interrogate to work on windows (VC8). It was sometime frustrating, so I have documentated everything, if someone ever needs to use it:

[size=150]Panda3D Interrogate[/size]

Requirements:
Windows (7)
Visual Studio 2008
Panda3D 1.8.1 SDK

This small tutorial shall show the basics of creating a python module with interrogate to extend panda3d. Only proceed to the next step, if you get no errors.

Notice: I did not test all code yet, but copied it from another project. If there are syntax errors, or typing errors, please tell me :slight_smile:

[size=150]Step 1 - New Project[/size]

Create a new project in VC (Win32-DLL). Follow these instructions while creating it:
panda3d.org/manual/index.ph … nguage=cxx
but exclude “libp3pystub.lib” from the libraries. Also do not forget to remove the “NDEBUG” from the preprocessing definitions.

[size=150]Step 2 - Some fixes[/size]

Go to your “dllmain.cpp” and comment out the DllMain function. It is not needed for an extension. Then open the “stdafx.h”, which VS should have created, and change it to:


// IMPORTANT
// No include guards here
// See https://discourse.panda3d.org/t/solved-can-i-use-multiple-classes-in-a-interrogate-lib/13707/1

// C4273: Inconsistent DLL-Binding
#pragma warning (disable: 4273)

// Define these constants for interrogate
#ifdef P3_INTERROGATE
#define WIN32
#define WIN32_VC
#define _WINDOWS
#endif

// Include the config of the panda3d installation. 
// This will ensure we have the same settings.
#include "dtool_config.h"
#undef DO_MEMORY_USAGE

// Import panda base
#include "pandabase.h"

When you are ready with that, navigate to /include/parser-inc/windows.h, and comment out the following lines:

union LARGE_INTEGER {
  __int64 QuadPart;
};

[size=150]Step 3 - Creating the interrogate command bat[/size]

Now create a bat file in your folder, and name it to “run_interrogate.bat”. Put the following content inside:

interrogate -D__inline -DCPPPARSER -DP3_INTERROGATE=1 -D__cplusplus -fnames -string -refcount -assert -S<Panda3D Path>\include\parser-inc -S<Panda3D Path>\include -I<Panda3D Path>\include -oc <Your Module Name>_igate.cxx -od <Your Module Name>.in -python-native *.h -module <Your Module Name> -library <Your Module Name> -Dvolatile=

interrogate_module -python-native -module <Your Module Name> -library <Your Module Name> -oc <Your Module Name>_module.cxx <Your Module Name>.in

Where:
stands for the root path of your Panda3D installation.
stands for the name of your module

[size=150]Step 4 - Creating a test class[/size]

Create a new class in your project. For example:

// DemoClass.h
#ifndef DEMOCLASS_H
#define DEMOCLASS_H

#include "stdafx.h"

class EXPCL_PANDASKEL DemoClass
{
PUBLISHED:
    
    // every exposed class, which is not static, needs a constructor and destructor
    DemoClass(void);
    ~DemoClass(void);

    static const char* sayHello();
};
#endif
// DemoClass.cpp
#include "DemoClass.h"

DemoClass::DemoClass(void) {}
DemoClass::~DemoClass(void) {}

const char *DemoClass::sayHello() 
{
    return "Hello World!";
}

[size=150]Step 5 - Running interrogate the first time[/size]

Run the in Step 3 created bat file (run_interrogate.bat) once. It should output:

Referencing Library <Your Module Name>

and nothing else. Now there should be the files “_igate.cxx” and “_module.cxx” in the project folder. Include these to your project.

[size=150]Step 6 - Auto run interrogate each build[/size]

Go to Project > Properties > Build-Events > Pre-Build-Event. In the command line enter:

echo Compiling Interrogate
run_interrogate.bat

So you do not have to manually run interrogate before every build. :slight_smile:

[size=150]Step 7 - Compile[/size]

Now you should able to compile Project. You should get no warnings. When it is finished, copy the generated dll and paste it in a new folder. Change the name to “.pyd”. In that folder, create a simple python file, to test your generated module. For example:

import <Your Module Name>

print "Module Functions =",dir(<Your Module Name)
print "Some Greetings:", <Your Module Name>.DemoClass.sayHello()

[size=150]Step 8 - Integrate with Panda3D[/size]

Now we will try to pass a Vec3 to our class, print out it’s x value, and increase it by 5. We modify our DemoClass to the following:

// DemoClass.h
#ifndef DEMOCLASS_H
#define DEMOCLASS_H

#include "stdafx.h"
#include "LVecBase3.h"

class EXPCL_PANDASKEL DemoClass
{
PUBLISHED:
    
    // every exposed class, which is not static, needs a constructor and destructor
    DemoClass(void);
    ~DemoClass(void);

    static const char* sayHello();
    static void someVectorOperation(LVecBase3 *vec);
};
// DemoClass.cpp
#include "DemoClass.h"

DemoClass::DemoClass(void) {}
DemoClass::~DemoClass(void) {}

const char *DemoClass::sayHello() 
{
    return "Hello World!";
}

void DemoClass::someVectorOperation(LVecBase3 *vec) {
    printf("Vector = LVecBase3(%f,%f,%f)\n", vec->get_x(), vec->get_y(), vec->get_z());
    vec->set_x(vec->get_x() + 5.0f);
}

Now do step 7 again, but modify your test file:

import <Your Module Name>
from panda3d.core import *

print "Module functions =",dir(<Your Module Name)
testVector = LVecBase3(1,2,3)
// Should output:
// Vector = LVecBase3(1.000,2.000,3.000)
<Your Module Name>.DemoClass.someVectorOperation(testVector) 

// Should output something like
// LVecBase3(6,2,3) 
print "New vector =",testVector

If you get the expected result, everything worked!

[size=150]Notes[/size]

  • Interrogate does not support volatile. There is a "Dvolatile= " added to the command line, to fix it.

  • Interrogate does not support structs extending structs without a declerator. Be sure you did not miss the public keyword.

  • IMPORTANT: When you are compiling for a version, this version has to be the first entry in your path! I tried to compile for 1.8.1 while my path was something like “C:\Panda3D-1.9.0\bin;C:\Panda3D-1.8.1\bin” - no chance to get it to work … it had to be “C:\Panda3D-1.8.1\bin;C:\Panda3D-1.9.0\bin” (simplified).

Thanks for reading this.
Tobias

1 Like