2010-10-14 8 views
1

J'écris actuellement un ensemble de fonctions wrapper de Qt4 pour une application en tant que plugin (car je pense personnellement que l'écriture d'extensions en langage C simple est plus facile à réaliser).Qt4 Wrapper provoque des erreurs de segmentation

Au début, je pensais que cela pourrait se faire par abstraire simplement ce qui suit:

#include <QApplication> 
#include <QPushButton> 

int main(int argc, char *argv[]) 
{ 
    QApplication* app = new QApplication(argc, argv); 
    QPushButton* hello = new QPushButton("Hello world!"); 
    hello->resize(500, 300); 
    hello->show(); 
    return app->exec(); 
} 

Dans ce (en fait, c'est le code dans main.c de mon emballage):

#include "bind.h" 

int main(int argc, char* argv[]) 
{ 
    gui_application_t* app; 
    gui_pushbutton_t* hello; 
    app = gui_application_new(argc, argv); 
    hello = gui_pushbutton_new("Hello World"); 
    gui_pushbutton_resize(hello, 100, 30); 
    gui_pushbutton_show(hello); 
    return gui_application_exec(app); 
} 

Alors que le premier fonctionne (comme prévu), j'obtiens des failles de segmentation à des endroits apparemment aléatoires dans le second. J'espérais ma version serait tout simplement faire la même chose que l'ancien ... mais je crains que ce ne est pas du tout :-(

Après avoir exécuté le binaire, la sortie est généralement:

*** GUI Debug: gui_application_new: ctx->app = hex_addr 
*** GUI Debug: gui_pushbutton_new: ctx->button = hex_addr 
*** GUI Debug: gui_pushbutton_resize: ctx->button = hex_addr 
*** GUI Debug: gui_pushbutton_show: ctx->button = hex_addr 
Segmentation fault 

Cependant, même après le retrait des appels à gui_pushbutton_* (et seulement appeler gui_application_new et gui_application_exec), l'application se bloque toujours, mais dans gui_application_exec

sortie de l'exécution du binaire avec gdb. http://codepad.org/wBifH1B2

Sources: http://dl.dropbox.com/u/863332/wrapper.tar.bz2

Toute aide est très appréciée, car cela m'a très perplexe ...

+0

Vous ne devriez pas appeler cela "bind". C'est déjà le nom d'une application de serveur DNS très populaire ainsi qu'un nom de fonction de socket BSD. Vous devriez également essayer d'inclure suffisamment de sources ici pour que cela soit tout à fait débogué. – nategoose

+0

@natgoose Je ne suis pas sûr de ce que vous voulez dire, "bind" est seulement le nom du répertoire que j'ai utilisé ici. En outre, l'archive comprend toutes les sources que j'ai écrites. sauf si vous voulez aussi que j'inclue la distribution complète des sources Qt4 ... :-) –

+0

J'ai modifié la question avec le fichier d'en-tête renommé. –

Répondre

0

Un appel à gui_allocate:

ctx = gui_allocate<gui_pushbutton_t>(sizeof(gui_pushbutton_t*)); 

suggère que la fonction fonctionne comme malloc et prend une demande taille et renvoie une adresse à un tampon de cette taille, mais ce n'est pas le cas. C'est une fonction gérée par un modèle, et chaque version connaît le type. Il est vraiment plus comme calloc que malloc parce que l'appel:

ctx = gui_allocate<gui_pushbutton_t>(1); 

allouerait suffisamment d'espace pour un gui_pushbutton_t. Le paramètre gui_allocate est une longueur de tableau, pas une taille d'élément.

Vous allouiez un tableau d'entre eux avec la longueur sizeof(gui_pushbutton_t *). Je ne vois pas vraiment comment cela causerait des fautes de segmentation car cela devrait entraîner une plus grande mémoire que nécessaire, à moins que ce soit le constructeur ou une autre action de la part de ces membres de la matrice qui cause votre problème.

+0

l'erreur de segmentation ne se produit pas dans l'appel à gui_allocate - cependant, gui_allocate en général est une mauvaise habitude pour moi. Je pourrais aussi avoir écrit 'gui_pushbutton_t * ctx = new gui_pushbutton_t;' qui ferait exactement la même chose ... d'une manière plus saine. –

+0

J'ai modifié les sources pour répondre à ce que vous avez indiqué. –

+0

La segfault se produit dans 'strlen' (__strlen_sse2) appelé par' int XSetCommand (affichage * d, fenêtre w, char * argv, int argc) '. Essayez d'écrire 'size_t __strlen_sse2 (const char * s) {size_t z = 0; while (* (s + z)) {z ++} renvoie z;} 'dans' main.c' et place un point d'arrêt dedans et regarde ce qui est passé. Vous devrez peut-être jouer avec le nom (en utilisant régulièrement 'strlen' ou' __strlen') pour l'utiliser avec votre version. – nategoose

Questions connexes