I am working with fifo module...I actually found the basic code on DaniWeb, just made a few changes to it...

There are 2 main sources...first one is called fifoqueue which consists of basic fifo functions i.e. qu, dequ, isEmpty and a couple more...the second one is called packetstructure which is the basic structure of a packet I want to give as my input...

Here's the entire code...

fifoqueue.h

#ifndef FIFOQUEUE_H 
#define FIFOQUEUE_H

#include <iostream>
#include "packetstructure.cpp"

using namespace std;

#define SIZE 20

class QueueClass
{
	packet queue[SIZE]; 
	int head, tail;
public:
	QueueClass(int, int);
	~QueueClass() {};
	void qu(packet chunk);
	packet dequ();
	int size();
	int isEmpty();
	int charToIntArrays(char);
	int charToIntPointers(char);
};

#endif

fifoqueue.cpp

#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)

#include "fifoqueue.h"

QueueClass::QueueClass(int a, int b)
{
	head = a;
	tail = b;
}

void QueueClass::qu(packet chunk)
{
	if(tail+1==head || (tail+1==SIZE && !head))
	{
		cout << "Queue is full\n";
		return;
	}
	tail++;
	if(tail==SIZE) tail = 0;
	queue[tail] = chunk;
}

packet QueueClass::dequ()
{
	if(head==tail)
	{
		cout << "Queue is empty\n";
		return NULL;
	}
	head++;
	if(head==SIZE) head = 0;
	return 0;
}

int QueueClass::size()
{
	int j = 0;
	for(; j<tail; j++) {}
	return j;
}

int QueueClass::isEmpty()
{
	if(head == tail)
	{
		cout << "Queue is empty\n";
		return 1; 
	}
	else return 0;
}

int charToIntArrays(char ch[])
 {
	 int value = atoi(&ch[0]);
	 return value;
 }

 int charToIntPointers(char *ch)
 {
	 int value=atoi(ch);
	 return value;
 }

#endif
#endif

packetstructure.cpp

#include <iostream>
 using namespace std;

 class header
 {
 public:
	 unsigned char offset[3];
	 unsigned char forwardingLabel[64];
	 unsigned char trailerOffset[3];
	 unsigned char privateFrameLimit[3];
	 unsigned char publicSize[3];
};

 class content
 {
 public:
	 unsigned char * payload;
 };

 class trailer
 {
 public:
	 unsigned char * trailer1;
	 unsigned char * trailer2;
 };

 class packet
 {
 public:
	 header myHeader;
	 content myContent;
	 trailer myTrailer;
 };

I am getting these 4 errors (I am commenting them in main)...

main.cpp

#include <iostream>
#include "fifoqueue.cpp"

using namespace std;

int main()
{
	QueueClass queue1(1,1);
/*Error1:- error C2065: 'QueueClass' : undeclared identifier;
Error2:- error C2146: syntax error: missing ';' before identifier 'queue1';
Error3:- error C3861: 'queue1': identifier not found*/

	cout<<"1 if queue is empty, 0 if queue is full. Result:"<<queue1.isEmpty()<<endl; /*Error4:- error C2228: left of '.isEmpty' must have class/struct/union*/
	return 0;
}

The funny thing is I was not getting these errors earlier. And all the changes that I have made to the code should not have affected these lines of codes at all.
I am not sure if this is going to help- When I started the program Visual Studio gave this message "The line endings in the following file are not consistent. Do you want to normalize the line endings?". I was not sure how to normalise a file. But I haven't got the message again.
I am unable to resolve them. Can someone please help.

Recommended Answers

All 20 Replies

in main.cpp try changing
#include "fifoqueue.cpp"
to
#include "fifoqueue.h"
then recompile and see what happens.

I get a different set of errors if I do that...

Error1:- error LNK2019: unresolved external symbol "public: int __thiscall QueueClass::isEmpty(void)" (?isEmpty@QueueClass@@QAEHXZ) referenced in function _main main.obj

Error2:- error LNK2019: unresolved external symbol "public: __thiscall QueueClass::QueueClass(int,int)" (??0QueueClass@@QAE@HH@Z) referenced in function _main main.obj

Error3:- fatal error LNK1120: 2 unresolved externals C:\Users\Neha\Documents\Visual Studio 2005\Projects\fifoqueue\Debug\fifoqueue.exe

I get a different set of errors if I do that...

Good, if the first error message went away then you probably fixed that problem. It's not uncommon to get a fresh bathch of errors when you've fixed the first one.

Now in fifoqueue.h change this line:
#include "packetstructure.cpp"
to this line:
#include "packetstructure.h"
recompile and see what happens.

By the way, do you see a pattern to the problem? You include .h files, not .cpp.

In addition you need to change the packetstructure.cpp file name to packetstructure.h as user defined type declarations belong in .h files, not .cpp.

Even after making the changes that you asked me to I am getting the exact same errors as above...

The point is that I have actually made this program run before i.e. by including the .cpp files...Ofcourse then it was very basic without any packetstructure and very simple classes...

I am unable to understand why i am getting these errors...When I seached for error LNK2019 in the msdn library the error occurs when-
1. there is a function inline problem i.e. an inline function has to be included in the header file
2. or if there is a problem with the function scope of a variable i.e. a variable declared within a function can only be used within the scope of that function.
3. or if there is a missing function body or variable
I have none of these problems...

And should I not be adding fifoqueue.cpp in my main as I am referring to the functions defined in that source...fifoqueue.h just has the function declarations...Could you explain?

Thanks.

I am really not sure why you have your class files in packetstructure.cpp.
The declarations should be in a file called packetstructure.h

As said before, you need to include packetstructure.h in fifoqueue.h, and then include fifoqueue.h in main.cpp and fifoqueue.cpp. The cpp files only need to reference your definitions, so that when the functions are called, the compiler knows the correct signature of those functions. The functions will be resolved by the compiler at link time, provided you have all of your files in the same project.

Now I presume you are using some kind of a syntax highlighter, so you can see that this define in your fifoqueue.cpp file

#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)

is basically commenting out ALL of your code !! So your compiler cannot see your class member function definitions.

I don't know what its purpose is really in this context, but fix it. Move your #endif's to the top or get rid of the #ifdef's. And your #ifdef's should be in your header or .h file.

You are right...NULL is causing the problem...The reason why I am using this piece of code is because I want member function dequ to return NULL value when the queue is empty...

packet QueueClass::dequ()
{
	if(head==tail)
	{
		cout << "Queue is empty\n";
		return NULL;
	}
	head++;
	if(head==SIZE) head = 0;
	return 0;
}

As you see dequ is of type packet, I do not know how to return a 0 or null value for this as 0is not working because it is an integer and false is binary...This is the error I get when I use NULL without defining it - error C2664: 'packet::packet(const packet &)' : cannot convert parameter 1 from 'int' to 'const packet &'...I am not really sure but could I use 'extern "C"' in some way here??

Could you suggest something...

You need to decide if your Queue is a queue of integers or a queue of packets. Your function declarations are all messed up.

For instance your head and tail pointers are ints, and your enqueue and dequeue functions use packets. They all need to be the same type.

Fix that first.

And then if your queue is empty your head and tail values will be set to a null pointer of the correct type and you can return one of those accordingly.

head and tail are integers as they specify the queue number i.e. head is the 1st buffer of the queue and tail (if the queue is full) is the 20th buffer (SIZE 20) of the queue...so if I give queue1(1,1) means that both point to the 1st buffer so buffer is empty...

Well your dequeue function needs to return a packet as per your definition. You cannot return NULL or 0 because they are both integers. So what you may want to do is check for IsEmpty() and if the queue is not empty then call dequeue and return queue[x] which would be a packet.

Well your dequeue function needs to return a packet as per your definition. You cannot return NULL or 0 because they are both integers. So what you may want to do is check for IsEmpty() and if the queue is not empty then call dequeue and return queue[x] which would be a packet.

First thing, the dequ function that I had quoted before had an error...I did not see it till today...

packet QueueClass::dequ()
{
	if(head==tail)
	{
		cout << "Queue is empty\n";
		return NULL;
	}
	head++;
	if(head==SIZE) head = 0;
	return queue[head];
}

The second return return queue[head] and not 0...

Apart from this I could do what you suggested but I would have to do it in main...I will have to first call isEmpty() everytime before I can call dequ()...I wanted the functionality of returning NULL to be built in dequ() itself...

You had once before suggested something about returning a null pointer...Can I use that? Could you give me an example...

Thanks.

You cannot return a pointer in one case, and "packet" in other. Both should be packets, or pointers. How do you want to use this function?

Why don't you try this instead ?

Define your dequeue function prototype as

bool dequeue(packet& mypacket){

  if (isEmpty()){
    return false;
  }
  head++;
  if(head==SIZE) head = 0;
  mypacket = queue[head];

  return true;
}

That worked!! Thanks a lot :) ...

Now I was trying to test if dequ() works fine...The charToIntArray function converts unsigned char to int and so does charToIntPointers function...I am not sure if I am writing this the right way...

I am commenting the errors that I am getting in the code...

int charToIntArrays(unsigned char ch[])
 {
	 int value = atoi(&ch[0]);/*Error1- error C2664: 'atoi' : cannot convert parameter 1 from 'unsigned char *__w64 ' to 'const char *' */
	 return value;
 }
int charToIntPointers(unsigned char *ch)
 {
	 int value=atoi(ch);/*Error2- error C2664: 'atoi' : cannot convert parameter 1 from 'unsigned char *' to 'const char *'*/
	 return value;
 }
#include <iostream>
#include "fifoqueue.h"

using namespace std;

int main()
{
	int offsetint;
	QueueClass queue1(1,1);
	cout<<"1 if queue is empty, 0 if queue is full. Result:"<<queue1.isEmpty()<<endl;
	packet somepacket;
	somepacket.myHeader.offset="123";/*Error3- error C2440: '=' : cannot convert from 'const char [4]' to 'unsigned char [3]'*/
	offsetint = charToIntArrays(offset);/*Error4- error C3861: 'charToIntArrays': identifier not found*/
	queue1.qu(somepacket);
	cout<<"dequeue:"<<queue1.dequ(somepacket)<<endl;
	return 0;
}

I am sorry if my questions are silly...

For this line here

somepacket.myHeader.offset="123";

Error3- error C2440: '=' : cannot convert from 'const char [4]' to 'unsigned char [3]

Your string as interpreted by the compiler is "123\0" .. where \0 is the string terminator. So actually the size of "123" is not 3 but 4. Do a "cout << strlen("123") << endl" and see.

Now you are trying to assign a const char string "123" of size 4 to your unsigned char offset array of size 3. First, you need allocate your array offset enough space to hold the string. Make it size 4 or higher depending on what you values you want to assign to it.

The second thing is that you cannot directly assign a const char array to an unsigned char array. I would suggest either using strcpy to copy the value over, or define offset as "string offset" using C++ strings, and then doing the assignment. C++ gives you the option to use the "string" datatype, so use it when you can.

Again, atoi() takes a const char* as an argument and returns an integer.

So you basically need something like :

int charToIntPointers(const char* ch)
 {
	 int value = atoi(ch);
	 return value;
 }

Although since your offset is already an integer in the main program I am not sure what you are trying to convert it to.

Remember that the C++ compiler is very strict about function prototypes, and variable definitions. So you need to make sure that you are passing in the correct arguments and argument types.

The reason why I am using unsigned char is because I want to assign memory to all the variables byte-wise...In a way (when you see the packetstructure) the header and trailer are always going to remain constant in a packet, only content is going to vary in size...The only way I can do this is by using unsigned char...

I tried using strcpy but it does not work for unsigned char...

Using char instead of unsigned char is not an option...So I have to use unsigned char to int casting...Can I use reinterpret_cast here?

If you want to convert your ascii to an int, you can use atoi.

You might be able to get away with this:
strcpy((char*)&(somepacket.myHeader.offset[0]),"123");

If you want to convert your ascii to an int, you can use atoi.

You might be able to get away with this:
strcpy((char*)&(somepacket.myHeader.offset[0]),"123");

It is still not working...i hope i have understood this right...u r typecasting const unsigned to char right?? so the output will be an array of char...but it is giving me errors...

I am sending the entire code again just for refreshing your memory as it has been a long time...

fifoqueue.h

#ifndef FIFOQUEUE_H 
#define FIFOQUEUE_H
#include <iostream>
#include "packetstructure.h"

using namespace std;

#define SIZE 20

class QueueClass
{
	packet queue[SIZE]; 
	int head, tail;
public:
	QueueClass(int, int);
	~QueueClass() {};
	void qu(packet chunk);
	bool dequ(packet &);
	int size();
	int isEmpty();
	int charToIntArrays(char[]);
	int charToIntPointers(char*);
};

#endif

packetstructure.h

#include <iostream>

 using namespace std;

 class header
 {
 public:
	 unsigned char offset[3];
	 unsigned char forwardingLabel[64];
	 unsigned char trailerOffset[3];
	 unsigned char privateFrameLimit[3];
	 unsigned char publicSize[3];
	 header();
};

 header::header()
 {
	 offset[3] = 0;
	 forwardingLabel[64] = 0;
	 trailerOffset[3] = 0;
	 privateFrameLimit[3] = 0;
	 publicSize[3] = 0;
 }

 class content
 {
 public:
	 unsigned char * payload;
	 content(){payload = 0;}
 };

 class trailer
 {
 public:
	 unsigned char * trailer1;
	 unsigned char * trailer2;
	 trailer(){trailer1 = 0; trailer2 = 0;}
 };

 class packet
 {
 public:
	 header myHeader;
	 content myContent;
	 trailer myTrailer;
	 packet () {header(); trailer(); content()}
 };

Can I write the pcket constructor the way I have?

fifoqueue.cpp

#include "fifoqueue.h"

QueueClass::QueueClass(int a, int b)
{
	head = a;
	tail = b;
}

void QueueClass::qu(packet chunk)
{
	if(tail+1==head || (tail+1==SIZE && !head))
	{
		cout << "Queue is full\n";
		return;
	}
	tail++;
	if(tail==SIZE) tail = 0;
	queue[tail] = chunk;
}

/*packet QueueClass::dequ()
{
	if(head==tail)
	{
		cout << "Queue is empty\n";
		return NULL;
	}
	head++;
	if(head==SIZE) head = 0;
	return queue[head];
}*/
bool QueueClass::dequ(packet& mypacket)
{
  if (isEmpty()){
    return false;
  }
  head++;
  if(head==SIZE) head = 0;
  mypacket = queue[head];

  return true;
}

int QueueClass::size()
{
	int j = 0;
	for(; j<tail; j++) {}
	return j;
}

int QueueClass::isEmpty()
{
	if(head == tail)
	{
		cout << "Queue is empty\n";
		return 1; 
	}
	else return 0;
}

int QueueClass::charToIntArrays(char ch[])
 {
	 int value = atoi(&ch[0]);
	 return value;
 }

int QueueClass::charToIntPointers(char *ch)
 {
	 int value=atoi(ch);
	 return value;
 }

main.cpp

#include <iostream>
#include <string>
#include "fifoqueue.h"

using namespace std;

int main()
{
	int offsetint;
	char offsetchar[3];
	QueueClass queue1(1,1);
	cout<<"1 if queue is empty, 0 if queue is full. Result:"<<queue1.isEmpty()<<endl;
	packet somepacket;
	offsetchar[3] = strcpy((char*)&(somepacket.myHeader.offset[0]), "123"); 
	offsetint = queue1.charToIntArrays(offsetchar[3]);
	queue1.qu(somepacket);
	cout<<"dequeue:"<<queue1.dequ(somepacket)<<endl;
	return 0;
}

I am still getting errors in the lines marked in red in main...

offsetchar[3] = strcpy((char*)&(somepacket.myHeader.offset[0]), "123");

If you define "char offsetchar[3]", then it contains:
offsetchar[0], offsetchar[1], offsetchar[2], not 3!

And that's also reason for second line too

I am getting the same errors whatever I change the value to...
Error 1: error C2440: '=' : cannot convert from 'char *' to 'char'
Error2: error C2664: 'QueueClass::charToIntArrays' : cannot convert parameter 1 from 'char' to 'char []'
The errors are not making any sense to me...

OK. Error 1:
offsetchar[2] is actually char.
And strcpy (what_ever) returns string (which is char ptr), so you have char = char*, it can't be

Error 2:
You have definition of that function:

int charToIntArrays(unsigned char ch[]);

It takes array of unsigned char's, and in main you call:

charToIntArrays(offsetchar[3]);

So you are providing it with only char, and not char*.

Basically, what is your offsetchar? maybe it should be array of strings? But string is already an array of chars, so maybe you should make offsetchar a matrix? (2D array)
I haven't read the whole code so I can't help you more, but I believe this is enough

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.