PDA

View Full Version : Problems with scope and C header functions



waldowoc
4th August 2008, 02:37
The problem is that my instruction in QT 4 was limited mainly to the GUI, which I understand great. But it lacks in practical application. In other words, I'm having trouble getting my GUI code to blend with the libyahoo2 (http://libyahoo2.sourceforge.net/) functions. The specific problem I'm getting is during the compile stage and appears to be dealing with scope.

See, I have a struct that should be global;


struct yahoo_local_account {
char yahoo_id[255];
char password[255];
int id;
int fd;
int status;
char *msg;
};

static yahoo_local_account * ylad = NULL;

And then I have a member function, which should have access to the global struct, right?;


void YahooLogin::okClicked()
{

// accept QString input
QString username = lineEditUsername->text();
QString password = lineEditPassword->text();

// convert QString to string
std::string usrnm = username.toStdString();
std::string psswrd = password.toStdString();

// convert string to const char and assign struct values
std::strcpy(ylad->yahoo_id, usrnm.c_str());
std::strcpy(ylad->password, usrnm.c_str());

//get the session id from yahoo_init, which is a libyahoo2 function from <libyahoo2/yahoo2.h>
ylad->id = yahoo_init(ylad->yahoo_id, ylad->password);
}

This provides me with 2 separate compiler problems, 1st is that ylad is not declared in this scope, and 2nd is the reference to yahoo_init is undefined.

Now, obviously I am missing something. It was my understanding that if the struct is placed before the main() that it would be global, meaning that it would be accessible from every piece of code after it. But in order to remedy the 1st compile error, I have to move the struct (which I had located in its own file yahoo2.cpp, which was in-turn #included in my main.cpp) directly into the yahooLogin.cpp file above the member function, and ylad's declaration actually in the okClicked() member function.

That still leaves 2 problems, 1. is that now the struct is definitely not global and therefore useless beyond the okClicked member function, and 2. is that I still get the compile error with the call to yahoo_init().

Errors:

1st:

yahoologin.cpp: In member function ‘void YahooLogin::okClicked()’:
yahoologin.cpp:27: error: ‘ylad’ was not declared in this scope
yahoologin.cpp:30: error: ‘yahoo_init’ was not declared in this scope

2nd:

yahoologin.o: In function `YahooLogin::okClicked()':
yahoologin.cpp:(.text+0x12b): undefined reference to `yahoo_init'
collect2: ld returned 1 exit status

Qt:


$ qmake --version
QMake version 2.01a
Using Qt version 4.2.1 in /usr/lib

Make:


$ make --version
GNU Make 3.81

Compiler:


$ g++ --version
g++ (GCC) 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)

lvi
4th August 2008, 08:43
Regarding yahoo_init(): did you include the libyahoo2 header files?

Regarding the global ylad: in the .cpp files where you want to use ylad, you need notify the compile of the existence of ylad:


extern struct yahoo_local_account * ylad;

The compile now knows that ylad is defined elsewhere.

(but I think you should try and avoid global variables...)

PS: I think this should be in General Programming ;)

waldowoc
4th August 2008, 18:35
PS: I think this should be in General Programming ;)

Yeah, I am a newbie to QT and I was thinking that the problem(s) I am having was due to some different way QT handles header files. But, I have also never had a practical use for C++ either, though I have read every resource I could get my hands on.

Does qt handle header files differently than C++ alone? I still should be able to access any function (or object in general) if it's header file is included at any point before the call, right?

Like, yahoo_init(), which is setup in the libyahoo2 header files...

lvi
4th August 2008, 20:25
Does qt handle header files differently than C++ alone? I still should be able to access any function (or object in general) if it's header file is included at any point before the call, right?

Like, yahoo_init(), which is setup in the libyahoo2 header files...
Yes, as long as you include the header files AND link the corresponding library files.
Now that I look back at your post:

yahoologin.cpp: In member function ‘void YahooLogin::okClicked()’:
yahoologin.cpp:27: error: ‘ylad’ was not declared in this scope
yahoologin.cpp:30: error: ‘yahoo_init’ was not declared in this scope
This error message tells that that probably you forgot to include the proper header files. The error in yahoologin.cpp:27 was probably fixed by declaring ylad as extern, as I mentioned before. The error in yahoologin.cpp:30 should be fixed by include the proper library header file.


yahoologin.o: In function `YahooLogin::okClicked()':
yahoologin.cpp:(.text+0x12b): undefined reference to `yahoo_init'
collect2: ld returned 1 exit status
This is a linker error. You should add the yahoo2 library to your .pro file to make sure it gets linked.

waldowoc
5th August 2008, 07:45
Thank you very much for your assistance.

Unfortunately, using extern only made things worse, lots of errors during compile time. :-(

About the header files, you came to the same conclusion I did, but, the header files have always been included in the code. When I first started getting the problem, I moved the libyahoo2 header file includes around to different .cpp files. I want it in the .cpp file with all the structs which is included in the main.cpp (because that makes more sense to me since it needs to be accessed several times throughout the program not just in yahooLogin()). I also tried including them in the main .cpp file, the mainwindow.cpp file and in the yahoologin.cpp file with no changes to the error. I tried putting them in ALL the files at the same time too. I even tried to #include them inside the member function, but that didn't work either.

Now, about this adding the library to the .pro file, is there a command line option for that? Or should I just edit it in an editor?

That would definitely prove it's a QT thing, especially since I can compile other programs (non QT) with the yahoo library just by including the libyahoo2 header files. The library is installed properly in the path.

lvi
5th August 2008, 11:29
What sort of error do you get using extern?

You should use it like this (simplified example):

main.cpp:


#include "somefile.h"

Yahoo_t* ylad;

int main(int argc, char* argv) {
/* do things */
return 0;
}


somefile.cpp


extern Yahoo_t* ylad;

/* other code */


So use extern in all but one cases to declare the variable globally.

---------------
I'm not sure what causes the problems with the header files. If you included the libyahoo2 headers everywhere, I can't see why it wouldn't be able to find yahoo_init().

You can add the lib to your .pro file or just add it in your Makefile. I'm not sure if there's a commandline option you can pass to qmake, maybe you can do something with the -after flag? I think adding the lib to LIBS with an editor is going to be the easiest option...