Thank you for the response Chris.
However, even after changing "static" to "extern" and declaring within the .cpp file globally, accessing the variable either through reference or direct, will modify the program execution and data received from my server.
If need be, I can upload the .cpp and .h files. However, I'll copy and paste the snippets below:
Credentials.h
#ifndef CREDENTIALSTYPES_H
#include "CredentialsTypes.h"
#endif
namespace Credentials
{
static loginSend_t loginSend; // #1
static serverLoginResponse_t serverLoginResponse; // #2
static clientVersion_t clientVersion; // #3
extern serverUpdateInformation_t serverUpdateInformation; // #4
...
#ifndef CREDENTIALSTYPES_H
#include "CredentialsTypes.h"
#endif
namespace Credentials
{
static loginSend_t loginSend; // #1
static serverLoginResponse_t serverLoginResponse; // #2
static clientVersion_t clientVersion; // #3
extern serverUpdateInformation_t serverUpdateInformation; // #4
...
To copy to clipboard, switch view to plain text mode
Credentials.cpp
namespace Credentials
{
serverUpdateInformation_t serverUpdateInformation;
int Login()
{
// Establish a new ServerSession().
quint32 ipAddress;
Credentials::serverUpdateInformation_t* pServerUpdateInformation = &Credentials::serverUpdateInformation;
// [B]Leaving in the above line, as you'll see below, ANYWHERE in this compilation unit will affect the ability of the QByteArray to receive information from the server[/B]
ipAddress = ((ipNotation.at(0).toLong()) << 24) | ((ipNotation.at(1).toLong()) << 16) |
((ipNotation.at(2).toLong()) << 8) | ((ipNotation.at(3).toLong()) << 0);
ServerSession s(ipString);
if (s.Connect() == ERROR_SUCCESS)
{
// Successfully connected. Client successfully sent the whole loginResponse_t structure to the server.
// Now we must read the serverLoginResponse_t structure.
int loginResponse = s.ParseLoginResponse();
if (loginResponse == ERROR_SUCCESS)
{
// Goal: Determine if we need to download any new patches or client.
// Attempt to send the server our version number.
if (s.SendVersionNumber() != ERROR_SUCCESS)
{
// There was an error sending our version number.
}
// Attempt to read the server's update information.
if (s.RecvUpdateInformation() != ERROR_SUCCESS)
{
// There was an error receiving update information.
}
// At this point we can parse the structure the serverUpdateInformation_t
//Credentials::serverUpdateInformation_t* pServerUpdateInformation = &Credentials::serverUpdateInformation;
// [B]Why does the above ^^^ and/or below screw up ServerSession's variable in the call to s.RecvUpdateInformation()?[/B]
//Credentials::serverUpdateInformation_t serverUpdateInformation_Copy = Credentials::serverUpdateInformation;
// Check to see if we need to update our client or not.
if (CURRENT_VERSION < clientUpdate.version)
...
namespace Credentials
{
serverUpdateInformation_t serverUpdateInformation;
int Login()
{
// Establish a new ServerSession().
QString dns = QLatin1String("login.xpextend.com");
QString ipString = QLatin1String("192.168.56.102");
QStringList ipNotation(ipString.split(QLatin1String(".")));
quint32 ipAddress;
Credentials::serverUpdateInformation_t* pServerUpdateInformation = &Credentials::serverUpdateInformation;
// [B]Leaving in the above line, as you'll see below, ANYWHERE in this compilation unit will affect the ability of the QByteArray to receive information from the server[/B]
ipAddress = ((ipNotation.at(0).toLong()) << 24) | ((ipNotation.at(1).toLong()) << 16) |
((ipNotation.at(2).toLong()) << 8) | ((ipNotation.at(3).toLong()) << 0);
ServerSession s(ipString);
if (s.Connect() == ERROR_SUCCESS)
{
// Successfully connected. Client successfully sent the whole loginResponse_t structure to the server.
// Now we must read the serverLoginResponse_t structure.
int loginResponse = s.ParseLoginResponse();
if (loginResponse == ERROR_SUCCESS)
{
// Goal: Determine if we need to download any new patches or client.
// Attempt to send the server our version number.
if (s.SendVersionNumber() != ERROR_SUCCESS)
{
// There was an error sending our version number.
}
// Attempt to read the server's update information.
if (s.RecvUpdateInformation() != ERROR_SUCCESS)
{
// There was an error receiving update information.
}
// At this point we can parse the structure the serverUpdateInformation_t
//Credentials::serverUpdateInformation_t* pServerUpdateInformation = &Credentials::serverUpdateInformation;
// [B]Why does the above ^^^ and/or below screw up ServerSession's variable in the call to s.RecvUpdateInformation()?[/B]
//Credentials::serverUpdateInformation_t serverUpdateInformation_Copy = Credentials::serverUpdateInformation;
// Check to see if we need to update our client or not.
if (CURRENT_VERSION < clientUpdate.version)
...
To copy to clipboard, switch view to plain text mode
ServerSession.cpp
...
int ServerSession::RecvUpdateInformation()
{
// Check to make sure the socket is currently connected.
{
// Populate magic values for PATCH_UPDATE_t and CLIENT_UPDATE_t.
snprintf(Credentials::serverUpdateInformation.patchUpdate.magic, strlen(PATCH_UPDATE_MAGIC), "%s", PATCH_UPDATE_MAGIC);
snprintf(Credentials::serverUpdateInformation.clientUpdate.magic, strlen(CLIENT_UPDATE_MAGIC), "%s", CLIENT_UPDATE_MAGIC);
char* contents;
int indexContents = 0;
while (!inputArray.contains(END_UPDATE_MAGIC))
{
this->tcpSocket->waitForReadyRead();
inputArray += this->tcpSocket->readAll();
}
contents = inputArray.data(); /* Pointer to data including NULL byte */
// "contents" is free()'d when QByteArray goes out of scope.
// Populate Credentials::serverUpdateInformation.
Credentials::serverUpdateInformation_t* pServerUpdateInformation = &Credentials::serverUpdateInformation;
memcpy(pServerUpdateInformation, contents, sizeof(Credentials::serverUpdateInformation.patchUpdate) -
sizeof(Credentials::serverUpdateInformation.patchUpdate.lists));
indexContents += sizeof(Credentials::serverUpdateInformation.patchUpdate) -
sizeof(Credentials::serverUpdateInformation.patchUpdate.lists);
...
...
int ServerSession::RecvUpdateInformation()
{
// Check to make sure the socket is currently connected.
if (this->tcpSocket->ConnectedState == QAbstractSocket::ConnectedState)
{
// Populate magic values for PATCH_UPDATE_t and CLIENT_UPDATE_t.
snprintf(Credentials::serverUpdateInformation.patchUpdate.magic, strlen(PATCH_UPDATE_MAGIC), "%s", PATCH_UPDATE_MAGIC);
snprintf(Credentials::serverUpdateInformation.clientUpdate.magic, strlen(CLIENT_UPDATE_MAGIC), "%s", CLIENT_UPDATE_MAGIC);
QByteArray inputArray;
char* contents;
int indexContents = 0;
while (!inputArray.contains(END_UPDATE_MAGIC))
{
this->tcpSocket->waitForReadyRead();
inputArray += this->tcpSocket->readAll();
}
contents = inputArray.data(); /* Pointer to data including NULL byte */
// "contents" is free()'d when QByteArray goes out of scope.
// Populate Credentials::serverUpdateInformation.
Credentials::serverUpdateInformation_t* pServerUpdateInformation = &Credentials::serverUpdateInformation;
memcpy(pServerUpdateInformation, contents, sizeof(Credentials::serverUpdateInformation.patchUpdate) -
sizeof(Credentials::serverUpdateInformation.patchUpdate.lists));
indexContents += sizeof(Credentials::serverUpdateInformation.patchUpdate) -
sizeof(Credentials::serverUpdateInformation.patchUpdate.lists);
...
To copy to clipboard, switch view to plain text mode
Basically, if I create or try to reference ANY variable of type serverUpdateInformation_t within Credentials::Login() it will effect the (QByteArray) inputArray receiving data from the server. Depending on where in Credentials::Login() I declare a variable of type serverUpdateInformation_t I have seen it lead to no socket data being read or socket data being interpreted incorrectly by the QByteArray data type, which expects the size of the QByteArray as the first qint16 (WORD) of data sent.
Why would declaring, for example, a completely-unrelated variable of type serverUpdateInformation_t affect what is going on within a different compilation unit, especially AFTER the function has been called before a declaration is made?!!!
Bookmarks