Due to unstable and unreliable mingw / MSYS2 behaviours on Windows 11 (x86_64), I have decided to use the Windows-native cl
compiler bundled with Visual Studio to compile Gtk 3 programs written in C. I am using Gtk 3 built with the
I have searched tirelessly on StackOverflow as well as the rest of the internet and have not found a solution that addresses my cl
-specific situation.
I have tried using /SUBSYSTEM:WINDOWS
which causes a compiler error because the compiler can't find WinMain hidden by Gtk. I have tried /D"subsystem,windows"
, /Dmwindows
as well as /Dsubsystem=gui
with and without the -
in front, but none solve the issue.
I have also tried this bit of code, which causes a huge amount of errors because the compiler can't find Windows-specific code hidden by Gtk:
#ifdef _WIN32
AllocConsole();
ShowWindow(GetConsoleWindow(), SW_HIDE);
#endif
Here is the test program:
#include <gtk/gtk.h>
static void activate (GtkApplication * app, gpointer user_data)
{
GtkWidget * window;
window = gtk_application_window_new (app);
gtk_window_set_title (GTK_WINDOW (window), "Hello internet from Gtk Windows!");
gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
gtk_widget_show_all (window);
}
int main (int argc, char ** argv)
{
GtkApplication * app;
int status;
app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
status = g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app);
return status;
}
I've elected not to post the compiler command-file contents as it's quite lengthy.
For those who may answer "Just use mingw, MSYS2, cygwin, etc" I'd rather stay with a cl
-specific solution please.
Is there a cl
-specific option for suppressing the console window when compiling and running C Gtk 3 programs on Windows?
A big thanks to Tony Lee for the recommendation! This code is working properly after specifying /SUBSYSTEM:WINDOWS
in the linker options:
#include <gtk/gtk.h>
static void activate (GtkApplication * app, gpointer user_data)
{
GtkWidget * window;
window = gtk_application_window_new (app);
gtk_window_set_title (GTK_WINDOW (window), "Hello internet from Gtk Windows!");
gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
gtk_widget_show_all (window);
}
#ifdef _WIN32
int WinMain (void * hInstance, void * hPrevInstance, char ** argv, int nCmdShow)
#else
int main (int argc, char ** argv)
#endif
{
GtkApplication * app;
int status;
app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
status = g_application_run (G_APPLICATION (app), 0, argv);
g_object_unref (app);
return status;
}
It should be noted that I had to put a zero for the argc
value in g_application_run()
, so that's another (minor) issue I'll have to figure out later, but if your Gtk program doesn't need to process command-line arguments, it's fine.
CodePudding user response:
The VS 2022 help on /SUBSYSTEM
under Windows
says to use it when:
The application doesn't require a console, probably because it creates its own windows for interaction with the user.
Which is exactly what's required here - There's a Raymon Chen article called "WinMain is just the conventional name for the Win32 process entry point" so when the OP found it undefined, it just needed to be declared instead of main
. It documents the WinMain
prototype as:
WinMain(HINSTANCE *, HINSTANCE *, char *, int)
However, MS documents the WinMain
prototype without the *
on HINSTANCE
in an article called "WinMain: The Application Entry Point" as
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow);
You could include Windows.h
but it doesn't appear there's a requirement to use hInstance
and hPrevInstance
so void *
should work as a substitute.