LINUX.ORG.RU

Сообщения nethoroth

 

Правильная передача указателей на ресурсы Gtk/ZeroMQ.

Форум — Development

Учусь писать на Gtk и ZeroMQ одновременно. В данный момент код ужасен чуть более, чем полностью, однако есть вещь, которая меня интересует более остальных. При использовании обоих библиотек функциям-обработчикам событий надо передавать некоторые ресурсы, такие как, например, контекст и сокеты от ZeroMQ. В связи с этим появились три структуры-обертки для передачи этих параметров. Мне это кажется очень уродливым и хотелось бы узнать нормальное решение. (Почему-то очевидное «сделать глобальные статические ресурсы» кажется мне не менее уродливым) Заранее спасибо за помощь =)

#include <gtk/gtk.h>
#include <zmq.h>
#include <stdlib.h>
#include <string.h>

#define BOX_SPACING 5

typedef struct
{
	GtkWidget *widget[5];
} WidgetSet;

typedef struct
{
	void *res[5];
} ZMQResourcesSet;

typedef struct
{
	WidgetSet * controls;
	ZMQResourcesSet * zmq;
} ResList;

static gboolean deleteEvent(GtkWidget *widget, gpointer data)
{
	return FALSE;
}

static void destroyEvent (GtkWidget *widget, gpointer data)
{
	ZMQResourcesSet t = *((ZMQResourcesSet *)data);
	zmq_close(t.res[1]);
	zmq_term(t.res[0]);
	gtk_main_quit();
}

static void buttonClicked (GtkObject *widget, gpointer data)
{
	WidgetSet IOControls = *(((ResList*)data)->controls);
	ZMQResourcesSet zmqRes = *(((ResList*)data)->zmq);
	void * context = zmqRes.res[0];
	void * sender = zmqRes.res[1];
	zmq_msg_t request, reply;
	int replyLen;
	char *answ, *text = gtk_entry_get_text((struct GtkEntry*)(IOControls.widget[1]));
	

	/*Send a message to server*/
	zmq_msg_init_size(&request, strlen(text));
	memcpy(zmq_msg_data(&request), text, strlen(text));
	zmq_send(sender, &request, 0);
	zmq_msg_close(&request);

	/*Recieve a reply from server*/
	zmq_msg_init(&reply);
	zmq_recv(sender, &reply, 0);
	replyLen = zmq_msg_size(&reply);
	answ = malloc (sizeof(char*)*(replyLen + 1));
	memcpy(answ, zmq_msg_data(&reply), replyLen);
	zmq_msg_close(&reply);
	answ[replyLen] = '\0';

	/*Change label text*/
	gtk_label_set_text((struct GtkLabel*)(IOControls.widget[0]), answ);
}

int main(int argc, char ** argv)
{
	GtkWidget *window;
	GtkWidget *label, *button, *textEntry, *vbox, *hbox;
	WidgetSet IOControls;
	void *context, *sender;
	ZMQResourcesSet ZmqRes;
	ResList reses = {&IOControls, &ZmqRes};

	gtk_init (&argc, &argv);
	context = zmq_init(1);

	/*Socket*/
	sender = zmq_socket(context, ZMQ_REQ);
	zmq_connect(sender, "tcp://localhost:5555");
	ZmqRes.res[0] = context;
	ZmqRes.res[1] = sender;
	
	/*Window*/
	window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
	g_signal_connect (window, "delete_event", G_CALLBACK(deleteEvent), NULL);
	g_signal_connect (window, "destroy_event", G_CALLBACK(destroyEvent), (gpointer)&ZmqRes);

	/*Label (main text area)*/
	label = gtk_label_new("Some text");

	/*Text Entrie*/
	textEntry = gtk_entry_new();
	
	/*Button*/
	button = gtk_button_new_with_label("OK");
	IOControls.widget[0] = label;
	IOControls.widget[1] = textEntry;
	g_signal_connect(button, "clicked", G_CALLBACK(buttonClicked), (gpointer)&reses);

	/*Widgets packing*/
	vbox = gtk_vbox_new (FALSE, BOX_SPACING);
	hbox = gtk_hbox_new (FALSE, BOX_SPACING);
	gtk_box_pack_start(GTK_BOX(hbox), textEntry, TRUE, TRUE, 0);
	gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
	gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0);
	gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
	gtk_container_add(GTK_CONTAINER(window), vbox);


	/*Finaly let us show widgets*/
	gtk_widget_show  (label);
	gtk_widget_show  (button);
	gtk_widget_show  (textEntry);
	gtk_widget_show  (hbox);
	gtk_widget_show  (vbox);
	gtk_widget_show  (window);
	gtk_main ();

	return 0;
}
nethoroth
()

Печаль: <netdb.h> и -ansi

Форум — Development
#include <netdb.h>

int main (void)
{
  struct addrinfo a;
  int b = AI_PASSIVE;
  return 0;
}

Если компилировать без опции -ansi все замечательно компилируется. А вот если ее добавить, то, во-первых, структура будет по мнению компилятора иметь неизвестный размер, а во-вторых (и это вообще не понятно) константа существовать не будет. Это баг или фича? Или это у меня в голове что-то не так?

nethoroth
()

new и bad_alloc

Форум — Development

Вот такой вот кусочек кода. Простите, если написал гавно, только начал переходить с си на си++.

#include <iostream>
#include <new>
#define BLOCK_SIZE 1024

int main ()
{
    char * a;
    unsigned long size = 0;
    for (size = 0;true;size += BLOCK_SIZE)
    {
        try
        {
            a = new char [BLOCK_SIZE];
        }
        catch (bad_alloc)
        {
            std::cout << a << " bytes allocated, can't allocate moar." << std::endl;
            return 1;
        }
    }
    return 0;
}
При компиляции получаем ошибку:
test.cpp:16: error: expected type-specifier before ‘bad_alloc’

Вроде как Шилдт пишет, что компилятор не обязательно должен обнулять указатель в случае ощибки, но вот bad_alloc дропнуть уж точно должен. А тут вроде как написано, что никаких таких исключений ему не известно даже. ЧЯДНТ?

nethoroth
()

RSS подписка на новые темы