Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » extern char and Allegro dialogs

This thread is locked; no one can reply to it. rss feed Print
extern char and Allegro dialogs
Elverion
Member #6,239
September 2005
avatar

I can't for the life of me figure out exactly what is going on here. Apparently, having an extern char being used in an Allegro dialog is causing a crash. In "main.h" and "mydlg.h", lets say, I have declared an extern char *. In "main.cpp", I have something similar to this: char *szString = new char[MAXLEN];. I am sure to strcpy(zsString, "something"), and check to make sure it works as a string. Everything looks ok, even when I use printf in "mydlg.cpp".

The problem comes when trying to use that string in the (dp) field of a dialog with do_dialog. The program just crashes. If I replace the string with (void*)"test" in the dialog, it does not crash.

Some code would probably help, eh? I'll be excluding any code that seems irrelevant.

main.h

//useless junk here
#include "connect_gui.h"
extern char *connect_ip;

main.cpp

#include "main.h"
char *connect_ip = new char[IP_MAXLEN+1];

int main()
{
  // setup stuff here
   InitConGUI();
  do_dialog(con_dlg, -1); // <-- crash happens HERE

  // extra, unrelated stuff here
}

connect_gui.h

#include "main.h"
extern char *connect_ip;

connect_gui.cpp

1 #include "connect_gui.h"
2 /*NOTE THIS NEXT LINE FOR LATER - commented for now*/
3 //char *connect_ip = new char[IP_MAXLEN+1];
4 
5 void InitConGUI()
6 {
7 strcpy(connect_ip, "127.0.0.1");
8 strcpy(connect_port, "1200");
9
10 printf("connect_ip: %s\nconnect_port: %s\n", connect_ip, connect_port);
11 system("pause");
12 }
13 
14DIALOG con_dlg[] =
15{
16 /* (proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) (dp2) (dp3) */
17 { d_text_proc, 48, 40, 56, 8, 255, 23, 0, 0, 0, 0, (void*)"IP/hostname: ", NULL, NULL },
18 { d_edit_proc, 160, 40, 120, 8, 255, 23, 0, 0, IP_MAXLEN, 0, connect_ip, NULL, NULL },
19 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
20};

Now, for that line I made note of in connect_gui.cpp...If I uncomment that line there, and comment out the same line in main.cpp [declaring connect_ip in connect_gui.cpp rather than main.cpp], the program works just fine. Because of this , I believe the problem is due to the externs.

In InitConGUI, use of the string works just fine no mater where the string is declared. Because of this, I'm quite sure the problem is not with the string itself, but something with the externs and the dialogs in combination.

As far as fixing this goes, I'm out of ideas. I could declare a temp string in connect_gui.cpp, yes, but I would rather fix the problem at the root rather than hack a cheep fix in there. Any ideas?

--
SolarStrike Software - MicroMacro home - Automation software.

Kitty Cat
Member #2,815
October 2002
avatar

I'm going to assume you are intentionally not showing more code, and that this isn't all of it.

The order objects are created/initialized between compilation units isn't defined. 'connect_ip' is probably NULL by the time the DIALOG struct is created, and is later set to something else. Never assume the order of global object initialization.

It's typically a bad idea to allocate in global space like that. It might be best of you do the new in InitConGUI:

if(!connect_ip)
{
   connect_ip = new char[IP_MAXLEN+1];
   con_dlg[1].dp = (void*)connect_ip;
}

Don't forget to delete[] connect_ip after you're all done with that dialog and before the program is shutdown.

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

Elverion
Member #6,239
September 2005
avatar

Hmm, you're right. I never thought about the order of global initialization. I've fixed my code based on your input. And, yes, I might not have been clear in my first post(or maybe I said too much and you just skimmed through it), but I did intentionally leave out a lot of code that I thought would have just been cluttering up the post, and was unrelated to the problem.

For the record, I originally did have the "connect_ip = new char[IP_MAXLEN+1];" part inside a function, but due to moving it around so much trying to fix the crashing leads to a mess till I can get the damn thing working.

My current, working "connection_gui.cpp" is as follows:

1#include "connect_gui.h"
2 
3char *connect_ip = NULL;
4char *connect_port = NULL;
5char *username = NULL;
6 
7void InitConGUI()
8{
9 // allocate space for these variables
10 if( !connect_ip )
11 connect_ip = new char[IP_MAXLEN+1];
12 if( !connect_port )
13 connect_port = new char[PORT_MAXLEN+1];
14 if( !username )
15 username = new char[USERNAME_MAXLEN+1];
16
17 // set them to their default values
18 strcpy(connect_ip, "127.0.0.1");
19 strcpy(connect_port, "1200");
20 strcpy(username, "Guest");
21
22 // modify the dialog
23 con_dlg[0].dp = (void*)connect_ip;
24 con_dlg[1].dp = (void*)connect_port;
25 con_dlg[2].dp = (void*)username;
26
27 set_dialog_color(con_dlg, 255, 23);
28}
29 
30DIALOG con_dlg[] =
31{
32 /* (proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) (dp2) (dp3) */
33 { d_edit_proc, 160, 40, 120, 8, 255, 23, 0, 0, IP_MAXLEN, 0, (void*)"", NULL, NULL },
34 { d_edit_proc, 160, 56, 120, 8, 255, 23, 0, 0, PORT_MAXLEN, 0, (void*)"", NULL, NULL },
35 { d_edit_proc, 160, 72, 120, 8, 255, 23, 0, 0, 4, 0, (void*)"", NULL, NULL },
36 { d_text_proc, 48, 40, 56, 8, 255, 23, 0, 0, 0, 0, (void*)"IP/hostname: ", NULL, NULL },
37 { d_text_proc, 48, 56, 104, 8, 255, 23, 0, 0, 0, 0, (void*)"Port: ", NULL, NULL },
38 { d_text_proc, 48, 72, 104, 8, 255, 23, 0, 0, 0, 0, (void*)"Nick: ", NULL, NULL },
39 { d_button_proc, 48, 96, 96, 16, 255, 30, 0, D_EXIT, 0, 0, (void*)"Connect", NULL, NULL },
40 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
41};
42 
43void CleanupConGUI()
44{
45 // delete our variables to prevent leakage
46 delete[] connect_ip;
47 delete[] connect_port;
48 delete[] username;
49
50 // set them all back to NULL
51 connect_ip = connect_port = username = NULL;
52}

You're suggestion for the InitConGUI really helped clean things up a bit and makes it easier to work with. Thanks.

Now that I've got it working, I just need to figure out how I want to remedy the fact that my dialog is blue and black, rather than white and gray. Looks completely different in the program than it does in the DLG editor found in the Utils section of this site. I suppose using 8bit color would work.

I would give you a cookie, but it appears that I created the topic wrong and cannot. It's the thought that counts, right?

--
SolarStrike Software - MicroMacro home - Automation software.

Dennis
Member #1,090
July 2003
avatar

Quote:

set_dialog_color(con_dlg, 255, 23);

Now that I've got it working, I just need to figure out how I want to remedy the fact that my dialog is blue and black, rather than white and gray.

Must be because of the values you pass there for foreground and background color.
They seem to refer to indices in some palette.
If your programme is ran in high or truecolor, then those values are interpreted as pixelcolor values, hence 255 could give 0000FF(rrggbb)==> blue and 23 could give 000017(rrggbb)==>extremely dark blue(might appear black).
Try: set_dialog_color(con_dlg,makecol(255,255,255),makecol(128,128,128));
Just make sure that you set those colors after setting the graphic mode, since makecol returns different values, depending on the current mode.

James Stanley
Member #7,275
May 2006
avatar

I don't have a clue if this helps, but I usually have a d_clear_proc as the first object in my dialogs, I don't know if you'd left it out as it's irrelevant. I don't know, really. I know this doesn't make any difference at all, but why do use (void*) as the type for the strings? I've used (char*) in all of mine. Does the Allegro Documentation say my way is bad or does it make no difference?

Go to: