Can't get a simple GTK3 application to work - c

All I want is just a simple dialog to select a file for processing.
I didn't use C lang for a while, and I can't find a good working example.
code:
#include <gtk/gtk.h>
#include <stdio.h>
int main(int argc, char const *argv[]) {
GtkFileChooserNative *native;
native = gtk_file_chooser_native_new ("Open File", NULL, GTK_FILE_CHOOSER_ACTION_OPEN, NULL, NULL);
return 0;
}
I compile it with this command:
gcc `pkg-config gtk+-3.0 --cflags` `pkg-config gtk+-3.0 --libs` -o out dialog.c
I am having segmentation fault on gtk_file_chooser_native_new ()
Maybe strace will help:
http://pastebin.com/TdC0A2J3

You need to call gtk_init (before any other GTK function), or have your own application class and call g_application_run. And your main should be int main(int argc, char**argv) as usual.
The following program does not segfault (on Linux/Debian/Sid, GTK is 3.22.7)
#include <gtk/gtk.h>
#include <stdio.h>
int main (int argc, char **argv) {
GtkFileChooserNative *native = NULL;
gtk_init (&argc, &argv);
native = gtk_file_chooser_native_new ("Open File", NULL,
GTK_FILE_CHOOSER_ACTION_OPEN, NULL, NULL);
guint res = gtk_native_dialog_run (GTK_NATIVE_DIALOG (native));
if (res == GTK_RESPONSE_ACCEPT) {
char *filename;
GtkFileChooser *chooser = GTK_FILE_CHOOSER (native);
filename = gtk_file_chooser_get_filename (chooser);
printf ("should open %s\n", filename);
g_free (filename);
}
/// in a real application perhaps you want: gtk_main ();
return 0;
}
and does show a dialog. Compile that using
gcc -Wall -g $(pkg-config gtk+-3.0 --cflags) \
$(pkg-config gtk+-3.0 --libs) \
-o out dialog.c
and use the gdb debugger when debugging.

Related

BCM2835_st_read() returns zero - confused

bcm2835 init works fine, as does all the GPIO & bcm2835_delay and the like.
RPi4 & Pi400, Raspbian "Bullseye", bcm2835 1.71, Libcap installed, added the program name etc
And I've compiled with Geany
gcc -Wall -o "%e" "%f" -pthread $(pkg-config gtk+-3.0 --cflags --libs) -export-dynamic -l bcm2835 -l png -DBCM2835_HAVE_LIBCAP
Here's code:
// bcm_timer.c
//
// Example program for bcm2835 library system time
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include <bcm2835.h>
uint64_t now = 0;
uint64_t then = 0;
uint rescode = 0;
int main(int argc, char **argv)
{
// Init GPIO
if ( ! bcm2835_init() )
{
printf("Fail 0x%X ", errno);
return -1;
}
then = bcm2835_st_read();
bcm2835_delay(500);
now = bcm2835_st_read();
printf("Then = 0x%lluX, Now = 0x%lluX \n", then, now) ;
bcm2835_close();
return 0;
}
Here's output:
xxx#raspberrypi:~/Develop/c/test $ ./bcm_timer
Then = 0x0X, Now = 0x0X

C: SDL Code compiling in ubuntu terminal but not in vscode

When I compile my code in the ubuntu terminal, it compiles perfectly, but when I execute the command in the VSCode integrated terminal, it gives me an error:
main.c:1:10: fatal error: no such file or directory
here's the command I use:
$ gcc main.c $(sdl2-config --cflags --libs) -o prog
and here is my code:
#include <SDL.h>
#include <stdio.h>
int main(int argc, char **argv) {
SDL_Window *window = NULL;
if(SDL_Init(SDL_INIT_VIDEO) != 0) {
SDL_Log("ERROR: SDL Initialization > %s\n", SDL_GetError());
exit(EXIT_FAILURE);
}
// program execution
window = SDL_CreateWindow("SDL2 Window", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, 0);
if(window == NULL) {
SDL_Log("ERROR: SDL Initialization > %s\n", SDL_GetError());
exit(EXIT_FAILURE)
}
SDl_Quit();
return EXIT_SUCCESS;
}

GIO library C: DBUS | GIOStream and GIOConnection

Trying to compile following code in C (I'm not very good with it) and getting Address boundary error. It seems like a variable is uninitialized.
all:
gcc -Wall -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include test.c `pkg-config --cflags dbus-1` `pkg-config --libs dbus-1 gio-unix-2.0`

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gio/gio.h>
#include <glib-2.0/glib.h>
int main (){
GIOStream stream;
GDBusConnectionFlags flags = G_DBUS_CONNECTION_FLAGS_NONE;
GError *gerr = NULL;
GDBusConnection * gcon = g_dbus_connection_new_sync(&stream,
NULL,
flags,
NULL,
NULL,
&gerr);
return 0;
}
Here is the documentation for GDBusConnection and GIOStream.
I can't understand what is wrong with the code. Can you explain?
After few more time I figured out that following works:
GInputStream * ginput = g_memory_input_stream_new();
GOutputStream * goutput = g_memory_output_stream_new (NULL, 0, realloc, free);
GIOStream * stream = g_simple_io_stream_new(ginput, goutput);
GDBusConnectionFlags flags = G_DBUS_CONNECTION_FLAGS_NONE;
GError* gerr = NULL;
GDBusConnection * gcon = g_dbus_connection_new_sync(stream,
NULL,
flags,
NULL,
NULL,
&gerr);
if (gerr){
printf(gerr->message, "%s");
}

Access main program from shared library in C

After some googling, I got shared libraries working quite well. I can open my module with dlopen and load functions with dlsym. However, this is always running functions from the library in the program, how do I use functions from my program in the library?
My simplified code:
main.c
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
int twice(int a){
return a*2;
}
int main(int argc, char ** argv){
char *plugin_name;
void *plugin;
int (*init)();
if(argc<2){
printf("give lib name\n");
return 0;
}
plugin = dlopen (argv[1], RTLD_NOW);
if (!plugin)
{
printf("Cannot load %s: %s\n",argv[1], dlerror ());
return 0;
}
init = dlsym (plugin, "init");
char * result = dlerror ();
if (result)
{
printf("Cannot find init in %s: %s\n", plugin_name, result);
return 0;
}
int res = init();
printf("result: %i\n",res);
return 0;
}
plugin.c
int init()
{
return twice(4);
}
Makefile:
all: main lib
main: main.c
gcc -ldl -o main main.c
lib: plugin.c
gcc -shared -o plugin.so plugin.c
And I run it with:
./main ./plugin.so
With Linux, glibc, and GNU ld you can run -rdynamic to your executable link flags. This will make all symbols in your executable visible to loadable modules, as if it were a shared library.
Note that this is not necessarily portable to other Unix-like systems.

undefined reference to `GlewInit' - OpenGL

I get this error when trying to make the executable, the code compiles correctly and yet when I hit the make command I get this error message:
gcc -c helloworld.c
lewis#lewis-desktop ~/Desktop/Dev/gl $ make
gcc -o hello-gl helloworld.o -L/usr/X11R6/lib -lGL -lglut -lGLEW -lm
helloworld.o: In function `Initialize':
helloworld.c:(.text+0x55): undefined reference to `GlewInit'
collect2: ld returned 1 exit status
make: *** [helloworld] Error 1
I'm running Linux Mint 13 and I think it's something to do with my makefile, I don't know too much about them so I hacked one together and found some code online:
GL_INCLUDE = /usr/X11R6/include
GL_LIB = /usr/X11R6/lib
GL_GLEW = /user/include
helloworld: helloworld.o
gcc -o hello-gl $^ -L$(GL_LIB) -lGL -lglut -lGLEW -lm
.c.o:
gcc -c -o $# $< -I$(GL_INCLUDE)
clean:
rm -f hello-gl hello-gl-dummy hello-gl.o util.o hello-gl-dummy.o
My Code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <GL/glew.h>
#include <GL/freeglut.h>
#define WINDOW_TITLE_PREFIX "Hello, World!"
int CurrentWidth = 600,
CurrentHeight = 400,
WindowHandle = 0;
void Initialize(int, char*[]);
void InitWindow(int, char*[]);
void ResizeFunction(int, int);
void RenderFunction(void);
int main(int argc, char* argv[])
{
Initialize(argc, argv);
glutMainLoop();
exit(EXIT_SUCCESS);
return 0;
}
void Initialize(int argc, char* argv[])
{
GLenum GlewInitResult;
InitWindow(argc, argv);
GlewInitResult = GlewInit();
if (GLEW_OK != GlewInitResult) {
fprintf(stderr, "ERROR: %s\n", glewGetErrorString(GlewInitResult));
exit(EXIT_FAILURE);
}
fprintf(
stdout,
"INFO: OpenGL Version: %s\n",
glGetString(GL_VERSION)
);
glClearColor(0.2f, 1.0f, 0.8f, 0.3f);
}
void InitWindow(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitContextVersion(4, 0);
glutInitContextFlags(GLUT_FORWARD_COMPATIBLE);
glutInitContextProfile(GLUT_CORE_PROFILE);
glutSetOption(
GLUT_ACTION_ON_WINDOW_CLOSE,
GLUT_ACTION_GLUTMAINLOOP_RETURNS
);
glutInitWindowSize(CurrentWidth, CurrentHeight);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
char *states[] = {"Hello", "My", "Name", "Is", "Lewis"};
WindowHandle = glutCreateWindow(WINDOW_TITLE_PREFIX);
if(WindowHandle < 1) {
fprintf(
stderr,
"KERN_ERROR: Could not create a new rendering window.\n"
);
exit(EXIT_FAILURE);
}
glutReshapeFunc(ResizeFunction);
glutDisplayFunc(RenderFunction);
}
void ResizeFunction(int Width, int Height)
{
/*captures the resize data from the OS and assigns it to the global
variable CURRENT_WIDTH & CURRENT_HEIGHT */
CurrentWidth = Width;
CurrentHeight = Height;
glViewport(0, 0, CurrentWidth, CurrentHeight);
}
void RenderFunction(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/*the next line takes the data from the back-buffer to the screen */
glutSwapBuffers();
glutPostRedisplay();
}
The names for the GLEW functions should start from 'glew', not 'Glew'.
So it is
GlewInitResult = glewInit();
C is case-sensitive and all the OpenGL-related libs usually start the names of the functions with lowercase letters.

Resources