Use interrogate and NameError: name 'MemoryBase' is not defined

I am using interrogate to create a pyd module, however, when trying to import, I encountered the message: NameError: name 'MemoryBase' is not defined.

I use this interrogate launch string:

D:\Panda3D-1.10.16-x64\bin\interrogate.exe -D__inline -DCPPPARSER -DP3_INTERROGATE=1 -D__cplusplus -promiscuous -fnames -python-native -string -refcount -assert -S/d/Panda3D-1.10.16-x64/include/parser-inc -I/d/Panda3D-1.10.16-x64/include -I/d/git/imgui -oc module/loader_igate.cxx -od module/loader.in -srcdir src/gui p3imgui.cxx -module loader -library loader -Dvolatile=

As a result, they receive this message.

CallbackImGui derives from TypedObject, but does not define a get_class_type() function.

Next, I run interrogate_module:

D:\Panda3D-1.10.16-x64\bin\interrogate_module.exe -python-native -module loader -library loader -oc module/loader_module.cxx module/loader.in

Without any messages, the compilation of the module proceeds without errors, but when I try to import the module, I get the above message.

Pass -import panda3d.core to interrogate_module since your module uses types defined in panda3d.core.

Thanks, but that doesn’t change the situation. It may be necessary to check whether the specified headers are located on the paths.

There are some issues, but I don’t think they are related in any way. I’m not sure.

/d/Code/Cpp/ImGuiIntegration/Variant_4/src/gui/p3imgui.h:5:10: warning: Cannot find imgui_impl_win32.h
#include "imgui_impl_win32.h"
         ^~~~~~~~~~~~~~~~~~~~
/d/Code/Cpp/ImGuiIntegration/Variant_4/src/gui/p3imgui.h:6:10: warning: Cannot find imgui_impl_opengl3.h
#include "imgui_impl_opengl3.h"
         ^~~~~~~~~~~~~~~~~~~~~~
/d/Code/Cpp/ImGuiIntegration/Variant_4/src/gui/p3imgui.h:8:10: warning: Cannot find callbackObject.h
#include <callbackObject.h>
         ^~~~~~~~~~~~~~~~~~
/d/Code/Cpp/ImGuiIntegration/Variant_4/src/gui/p3imgui.h:9:10: warning: Cannot find callbackData.h
#include <callbackData.h>
         ^~~~~~~~~~~~~~~~
/d/Panda3D-1.10.16-x64/include/pnotify.h:190:5: warning: Ignoring invalid expression __cplusplus >= 201103
#if __cplusplus >= 201103
    ^~~~~~~~~~~~~~~~~~~~~
CallbackImGui derives from TypedObject, but does not define a get_class_type() function.

It looks like interrogate is very syntax sensitive.

/d/Code/Cpp/ImGuiIntegration/Variant_4/src/gui/p3imgui.h:5:10: warning: Cannot find imgui_impl_win32.h
#include "imgui_impl_win32.h"
         ^~~~~~~~~~~~~~~~~~~~
/d/Code/Cpp/ImGuiIntegration/Variant_4/src/gui/p3imgui.h:6:10: warning: Cannot find imgui_impl_opengl3.h
#include "imgui_impl_opengl3.h"
         ^~~~~~~~~~~~~~~~~~~~~~
/d/Panda3D-1.10.16-x64/include/pnotify.h:190:5: warning: Ignoring invalid expression __cplusplus >= 201103
#if __cplusplus >= 201103
    ^~~~~~~~~~~~~~~~~~~~~
/d/Panda3D-1.10.16-x64/include/callbackObject.h:37:63: error: syntax error, unexpected IDENTIFIER, expecting '{' or ';' or ':' or '='
  EXTENSION(static PT(CallbackObject) make(PyObject *function));
                                                              ^
interrogate failed to parse file: 'p3imgui.cxx'

Replacing brackets with quotation marks allows you to find the head.

#include <callbackObject.h>
#include <callbackData.h>

On

#include "callbackObject.h"
#include "callbackData.h"

However, now there is a syntax error.

/d/Panda3D-1.10.16-x64/include/callbackObject.h:37:63: error: syntax error, unexpected IDENTIFIER, expecting '{' or ';' or ':' or '='
  EXTENSION(static PT(CallbackObject) make(PyObject *function));
                                                              ^
interrogate failed to parse file: 'p3imgui.cxx'

The quirk is that the Microsoft compiler doesn’t care, it compiles without problems.

EXTENSION() is defined to nothing for the Microsoft C++ compiler, that’s why it doesn’t care.

Are you using using namespace std; anywhere? It’s possible that the argument name function conflicts with std::function. I know there used to be a parser bug in interrogate that caused issues with this. This may be fixed in the current version of interrogate.

@rdb
Are you by any chance a psychic? Yes, I use it.

#ifndef CALLBACKIMGUI_H
#define CALLBACKIMGUI_H

#include "pandabase.h"

#include "imgui.h"
#include "imgui_impl_win32.h"
#include "imgui_impl_opengl3.h"

#include "callbackObject.h"
#include "callbackData.h"
#include "displayRegion.h"
#include "graphicsWindow.h"
#include "graphicsOutput.h"

#include <functional>
#include <iostream>
#include <map>

class CallbackImGui : public CallbackObject{
    private:
        PT(DisplayRegion) display_region;
        PT(GraphicsWindow) graphics_window;
        PT(GraphicsOutput) graphics_output;
        PT(ButtonEventList) button_event_list;
        ButtonEvent button_event;
        InputDevice* input_device;
        
        // Переменная для разграниения типа ввода, 0 это приложение, 1 это клавиши, 2 это текстовый ввод.
        int status_input;

        virtual void do_callback(CallbackData* cbdata);
        void send_mouse_code_imgui(ButtonEvent button_event);
        void send_board_code_imgui(ButtonEvent button_event);
        void send_unicode_code_imgui(ButtonEvent button_event);

        // Переменная для хранение старого размера дисплея между кадрами.
        ImVec2 old_display_size;

        // Словарь для хранения состояний кнопок мыши.
        std::map <std::string, int> state_keys_mouse;
        // Словарь для хранения состояний кнопок клавиатуры.
        std::map <std::string, ImGuiKey> state_keys_board;

    public:
        ALLOC_DELETED_CHAIN(CallbackImGui);
        CallbackImGui(PT(DisplayRegion) initial_display_region);
        std::function<void()> instructions;
};

#endif

But when building Panda3D, don’t I automatically build the latest version of interrogate?

As of the master branch of Panda3D, interrogate is split into a separate project with its own versioning.

The 1.10.x releases are not built from the master branch, they have an older version of interrogate bundled.

An easy temporary workaround, by the way, is just to rename the “function” argument in the callbackObject.h header to something else. It won’t affect the ABI so you won’t need to recompile Panda.

It doesn’t seem to be a name issue.

/d/Panda3D-1.10.16-x64/include/pnotify.h:190:5: warning: Ignoring invalid expression __cplusplus >= 201103
#if __cplusplus >= 201103
    ^~~~~~~~~~~~~~~~~~~~~
/d/Panda3D-1.10.16-x64/include/callbackObject.h:37:62: error: syntax error, unexpected IDENTIFIER, expecting '{' or ';' or ':' or '='
  EXTENSION(static PT(CallbackObject) make(PyObject *funtest));
                                                             ^
interrogate failed to parse file: 'p3imgui.cxx'

I think I need to try out the new version of interrogate for an experiment.

With the new version of interrogate 0.8.0, the message looks different.

/d/Panda3D-1.10.16-x64/include/pnotify.h:190:5: warning: Ignoring invalid expression __cplusplus >= 201103
#if __cplusplus >= 201103
    ^~~~~~~~~~~~~~~~~~~~~
/d/Panda3D-1.10.16-x64/include/callbackObject.h:37:3: error: syntax error
  EXTENSION(static PT(CallbackObject) make(PyObject *function));
  ^
with EXTENSION() expanded to: __extension static PT(CallbackObject) make(PyObject *function)

Returning to the essence of the post, the problem when importing the module: NameError: the name 'MemoryBase' is not defined, it lies in the use of the -promiscuous flag, perhaps I misinterpreted its purpose.

The strangest thing is that after switching to another environment of a different project (a test run of interrogate for acquaintance), I stopped receiving a message from interrogate about syntax error in the callbackObject.h header file.

Now all I have to do is add the headers from ImGui to find out the source of the problem.

It looks like with the -promiscuous flag, something was exported that wasn’t in the core module. Does anyone know how to examine the file.pyd for dependencies on other modules?

It seems that when using the -promiscuous flag, the module becomes dependent on libp3pandatoolbase, however, this cannot be resolved on the python side, since there is no .pyd module.

Yes, the use of that flag did look odd to me. We don’t test with that flag, and it’s better to just mark things as PUBLISHED or list the interfaces you want to publish in an .N file.
With -promiscuous it probably gets a dependency on libp3pandatoolbase because it assumes that everything that your code includes also has Python bindings, which is not the case in your situation. I advise against using that flag.

As for the syntax errors in callbackObject.h, it’s unclear. The warning itself is because you defined __cplusplus to an empty token, you probably want to set it to a version number (or 1 at least). The error message could be that it doesn’t understand PT() or PyObject *, are you sure you didn’t miss some errors or warnings before that? Maybe it doesn’t have access to the parser-inc files where the stub of Python.h is located?

You can look at the libp3imgui_igate.cxx generated code, the imports should be somewhere in there. Or you can look at the .idb files, but they are not easy to read either.

I suggest finding the difference.
This does not result in a syntax error.

#ifndef EXAMPLE_H
#define EXAMPLE_H

#include "pandabase.h"
#include "dtoolbase.h"
#include "nodePath.h"
#include "callbackObject.h"

#endif EXAMPLE_H

This results in a syntax error.

#ifndef EXAMPLE_H
#define EXAMPLE_H

#include "pandabase.h"
#include "dtoolbase.h"
#include "callbackObject.h"

#endif EXAMPLE_H

It seems to me make macros is lost somewhere. I’m not very familiar with the concepts of the C++ language, so I’ll leave it to the experts.

I added this for clarity, since it does not affect the syntax error in any way.

#include "pandabase.h"
#include "dtoolbase.h"

The NodePath header contains the necessary macro somewhere, but I have no idea where to find it.

I have narrowed down the necessary headers, in order to eliminate the syntax error, it is enough to include this header.

#include "pointerTo.h"

I think we can explore this further.

By the way, the parser-inc files lacks a stub for this, I think that’s the problem.

Ah, it’s possible that that include is missing from callbackObject.h, but that the error is normally hidden because other headers just happen to be included first. I will check in a fix to panda3d.

It doesn’t need a parser-inc stub since interrogate should be pointed at the real headers.

@rdb
The question for the future is, if interrogate finds a syntax error in an extraneous code, does this mean that me need to create a parser-inc header with a brief definition of the object.

For example, I used BEGIN_PUBLISH and END_PUBLISH in the original imgui.h

BEGIN_PUBLISH

// Forward declarations: ImDrawList, ImFontAtlas layer
struct ImDrawChannel;               // Temporary storage to output draw commands out of order, used by ImDrawListSplitter and ImDrawList::ChannelsSplit()
struct ImDrawCmd;                   // A single draw command within a parent ImDrawList (generally maps to 1 GPU draw call, unless it is a callback)
struct ImDrawData;                  // All draw command lists required to render the frame + pos/size coordinates to use for the projection matrix.
struct ImDrawList;                  // A single draw command list (generally one per window, conceptually you may see this as a dynamic "mesh" builder)
struct ImDrawListSharedData;        // Data shared among multiple draw lists (typically owned by parent ImGui context, but you may create one yourself)
struct ImDrawListSplitter;          // Helper to split a draw list into different layers which can be drawn into out of order, then flattened back.
struct ImDrawVert;                  // A single vertex (pos + uv + col = 20 bytes by default. Override layout with IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT)
struct ImFont;                      // Runtime data for a single font within a parent ImFontAtlas
struct ImFontAtlas;                 // Runtime data for multiple fonts, bake multiple fonts into a single texture, TTF/OTF font loader
struct ImFontAtlasBuilder;          // Opaque storage for building a ImFontAtlas
struct ImFontAtlasRect;             // Output of ImFontAtlas::GetCustomRect() when using custom rectangles.
struct ImFontBaked;                 // Baked data for a ImFont at a given size.
struct ImFontConfig;                // Configuration data when adding a font or merging fonts
struct ImFontGlyph;                 // A single font glyph (code point + coordinates within in ImFontAtlas + offset)
struct ImFontGlyphRangesBuilder;    // Helper to build glyph ranges from text/string data
struct ImFontLoader;                // Opaque interface to a font loading backend (stb_truetype, FreeType etc.).
struct ImTextureData;               // Specs and pixel storage for a texture used by Dear ImGui.
struct ImTextureRect;               // Coordinates of a rectangle within a texture.
struct ImColor;                     // Helper functions to create a color that can be converted to either u32 or float4 (*OBSOLETE* please avoid using)

END_PUBLISH

Next, at the compilation stage of the module, I received this message.

D:\git\imgui\imgui.h(173,8): error C2144: syntax error: 'ImDrawChannel' should be preceded by ';' [D:\Code\Cpp\ImGuiIntegration\Variant_5\temp\test_my_module.vcxproj]
D:\git\imgui\imgui.h(173,21): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [D:\Code\Cpp\ImGuiIntegration\Variant_5\temp\test_my_module.vcxproj]
D:\git\imgui\imgui.h(196,8): error C2144: syntax error: 'ImGuiContext' should be preceded by ';' [D:\Code\Cpp\ImGuiIntegration\Variant_5\temp\test_my_module.vcxproj]
D:\git\imgui\imgui.h(196,20): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [D:\Code\Cpp\ImGuiIntegration\Variant_5\temp\test_my_module.vcxproj]

This would be the case if your module used Panda3D in a very limited fashion - ie. nothing about your use of Panda3D would be relevant to the bindings. For example, if you are do not need your functions to take Panda3D types as arguments, return Panda3D types, or inherit from Panda3D classes. Otherwise, interrogate really does need to know the full definition of the Panda3D types so that it will understand how to convert them.

This applies to Dear ImGui as well. Do you really need to wrap the imgui types themselves? If so, interrogate will probably need more than just a forward declaration.

Please note that there needs to be a proper definition of BEGIN_PUBLISH. It is normally defined in dtoolbase.h and defined to __begin_publish (an interrogate keyword) when CPPPARSER is set, or nothing if it is not. That error suggests you are either accidentally defining CPPPARSER when compiling, or dtoolbase.h is not included first.

No, I’m just being arrogant to understand how far i can go when creating bindings. At the moment, I’ve settled on the idea of creating custom wrappers from functions for ImGui functions.

For now, I have followed your advice and avoided syntax errors, but interrogate has not published the necessary (marked) structure.

Re-wrapping functions is a good way to go.