[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
[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.
[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