Search code examples
c++visual-c++gtk

Problem with the return type of Gtk4 function gtk_builder_new_from_string?


I'm trying to use the Gtk4 function gtk_builder_new_from_string but the type that it is returning isn't what I am expecting.

I have the following segment of C++ code which makes use of the Gtk4 GUI toolkit.

    #include <iostream>
    #include <string>
    #include <typeinfo>
    #include <gtk/gtk.h>
    #include <FileUtils.hpp>

    using namespace std;

    // Code omitted for the sake of brevity.

    int main(void)
    {
        string       xmlString;
        GtkBuilder * builder_p = NULL;


        readWholeFileIntoString("c:\\users\\craig\\Documents\\simple.ui", &xmlString);

        builder_p = gtk_builder_new_from_string(xmlString.c_str(), xmlString.length());
        cout << "Type of builder_p = " << typeid(builder_p).name() << endl;

        if (GTK_IS_BUILDER(builder_p))
        {
            // The following line of code seems to be causing problems at compile time!
            // If I comment it out, then the code compiles and executes successfully.

            builder_p->get_objects();
        }
        return 0;
    }

This segment of code is contained within a file which is called InvokeBuilder.cpp. When I attempt to compile this file from the command line, using nmake and the C++ compiler which ships with Visual Studio 2022, I get the following error;

InvokeBuilder.cpp
InvokeBuilder.cpp(89): error C2027: use of undefined type '_GtkBuilder'
c:\msys64\mingw64\include\gtk-4.0\gtk/gtktypes.h(39): note: see declaration of '_GtkBuilder'
NMAKE : fatal error U1077: '"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\bin\HostX64\x64\cl.exe"' : return code '0x2'
Stop.

When I look at line 39 of gtktypes.h on my system, as per the compilers suggestion, I see the following line;

typedef struct _GtkBuilder             GtkBuilder;

So if I'm not mistaken then, this line is simply telling me that GtkBuilder is just an alias for struct _GtkBuilder. Furthermore, I suspect the former has visibility outside of the header file, while the latter does not. In addition to this, the Gtk4 documentation for the gtk_builder_new_from_string function - which can be found at (https://docs.gtk.org/gtk4/ctor.Builder.new_from_string.html), states that this function should have the following prototype;

GtkBuilder*
gtk_builder_new_from_string
(
  const char* string,
  gssize length
)

When I look up the actual declaration for this function in gtkbuilder.h, I find the following;

GDK_AVAILABLE_IN_ALL
GtkBuilder * gtk_builder_new_from_string         (const char    *string,
                                                  gssize         length);

So why then is the Microsoft Visual Studio 2022 C++ compiler complaining about this? If I comment out the offending line of code, then it compiles and runs without a problem. So the GtkBuilder object seems to be created okay, it's just that it is a problem when I try and access it. I have tried using casts and some other tricks to try and convert the result of the gtk_builder_new_from_string, however they don't seem to be working for me.

When I run the resulting executable - with the offending line of source code commented out, I get the following output;

Type of builder_p = struct _GtkBuilder * __ptr64

I take this to mean that the result of the function is a 64-bit pointer to an object of type struct _GtkBuilder. Can anyone see why this is so, or deduce what is going on here? Is there some trick with Gtk that I am missing here, or do I need to download and compile myself, the latest version of Gtk4? Is it a problem with the Microsoft compiler? Will the GNU gcc compiler not have this problem? Or, is all of this better addressed on some Gtk mailing list?

And before someone suggests it, no - I do not want to abandon this function in preference for the gtk_builder_new_from_file function.


Solution

  • As it turns out, the offending line of code should be using the Gtk4 function gtk_builder_get_objects, in a fashion which is similar to the following:

    list_objects_p = gtk_builder_get_objects(builder_p);
    

    rather than trying to accomplish this task in the manner which it was going about it – that is:

    builder_p->get_objects();
    

    In an attempt to try and find a possible solution to my problem, I had been reading (https://python-gtk-3-tutorial.readthedocs.io/en/latest/builder.html) earlier in the day, and had forgotten that this web page was using the Python programming language rather than C/C++ to interact with Gtk, and this is where the offending line of code came from!