C++ link error LNK2005 - c++

I am new to C++ programing and I'm trying to make a program that simulates Conway's game of life. I'm almost done but when I made each function have it's own file I keep on getting this linker error.
1>algorithm_change.obj : error LNK2005: "unsigned short height" (?height##3GA) already defined in algorithm.obj
My code is at https://github.com/rupertsteel/Life/tree/master/Life

Without looking at the code, do you have a global unsigned short height; in any header file? If yes, replace that with extern unsigned short height; and put a unsigned short height; in a source file that includes the specific header.

A few comments:
1) array_length in life.h needs to be externed
2) All the externed variables (width, height, ticks, count_array, change_array, error_check, algorithm_length, array_length) need to be defined somewhere.
In your code you've basically told the compiler that those variables exist somewhere but haven't actually placed them in existence anywhere. In one of your .cpp files in the global scope you need to put:
unsigned short int width;
unsigned short int height;
unsigned long int ticks;
unsigned short int count_array[10923][10923];
bool change_array[10923][10923];
int error_check;
unsigned long int algorithm_length;
unsigned long int array_length;
Which is exactly the same as what you have in life.h, except without the extern keyword. This will actually create the variables, as opposed to now where they have no concrete implementation.
If you make the changes I suggest your code will compile (tested using gcc). That being said, the actual error you're seeing doesn't make sense.

Related

Using function declared in C++ dll and its VB declarations

There is a .dll and .lib file for the evaluation board AD5501 after installing its drivers. It contains the functions to use to connect to the board and send instructions to it.
A quick search in analog's website (https://ez.analog.com/thread/11121) revealed a document that contains the commands in the above mentioned DLL file. And it is mentioned that the DLL is written in C++. At the end of the page there is a pdf containing VB6 function declarations of the DLL.
I have no knowledge of VB6 but the fact that the DLL has been written in C++ led me to assume that I should be able to access the function in the DLL or LIB file if i know the function prototype in a C++ program. Is this a correct assumption?
And the website has description of the function prototype. So i made a test C++ program as given below :
#include <iostream>
using namespace std;
unsigned int Search_For_Boards (unsigned int VID, unsigned int PID, unsigned int *Num_boards, char *PartPath[]);
int Connect(unsigned int VID, unsigned int PID, char PartPath, unsigned int *Handle);
int Download_Firmware(unsigned int Handle, char pcFilePath[]);
int Vendor_Request(unsigned int Handle, unsigned char Request, unsigned short Value, unsigned short Index, unsigned char Direction, unsigned short DataLength, unsigned char *Buffer[]);
int Disconnect (unsigned int Handle);
int main(){
char *partpath[2];
unsigned int *num;
unsigned int vid = 1110;
unsigned int pid = 45617;
unsigned int error = Search_For_Boards(vid, pid, num, partpath);
cout<<"Hello\n"<<error<<endl;
return 0;
}
And on compiling the code in the following command:
g++ C:\test.cpp -L "C:\Program Files\Analog Devices\USB Drivers" -lADI_CYUSB_USB4
I get the error
Undefined reference to Search_For_Boards(unsigned int, unsigned, int, unsigned int*, char**)
meaning apparently the function prototype is not correct.
Now all this is ASSUMING that i can use the DLL in a C++ program. Seeing the document for VB6 function declaration made me thinking if my assumption is wrong. So my 2 questions are :
1) Is my assumption correct?
2) If the assumption is correct, What is the blunder i am doing here? I feel like I linked the library properly and to my best declared the prototype according to what is described.

Char Followed by a char is illegal (qglobal.h)

I searched this forum already and found a same question but it didn't solve and not even gave any clue in solving my problem. I am doing one project in which i am using Templates.
Firstly i used C++ map like this
typedef map<int ,cal_point*> p_mMap2D;
and it worked perfectly. Then i tried to make a GUI using Qt, but when i used "QMap", it gave an error that
typedef QMap<int ,cal_point*> p_mMap2D;
Error 25 error C2632: 'char' followed by 'char' is illegal C:\Qt
\4.7.4\include\QtCore\qglobal.h 897
Then i tried to use only map as i used before but still it is giving error. I searched net but didn't get any clue related to it. If i don't use Qt then its working perfectly.
Code from qtglobal.h
QT_BEGIN_INCLUDE_NAMESPACE
typedef unsigned char uchar;
typedef unsigned short ushort;
typedef unsigned int uint;
typedef unsigned long ulong;
QT_END_INCLUDE_NAMESPACE
Inside /src/corelib/global/qglobal.h Qt 4.8.5 contains following strings:
# define QT_BEGIN_INCLUDE_NAMESPACE }
# define QT_END_INCLUDE_NAMESPACE namespace QT_NAMESPACE {
And when preprocessor expands this macro with for example QT_NAMESPACE=qt result will be:
}
typedef unsigned char uchar;
typedef unsigned short ushort;
typedef unsigned int uint;
typedef unsigned long ulong;
namespace qt {
Looks like an error of definition QT_BEGIN_INCLUDE_NAMESPACE and QT_END_INCLUDE_NAMESPACE.
It is hard to tell because you have not included the definition of cal_point*, but the problem is where it is defined or somewhere among those lines. Check them. It might be in an external file that makes it break, and so on.

UINT32 compiler version mismatch - Linking to legacy library

I am trying to link a DLL but I am constantly running into issues with UINT32.
The library is compiled against the 4.1 version of the Visual Studio compiler. The interface for my component (which was 4.1 and I am now porting to 2012) is defined with many UINT32s in it. In VC4.1 UINT32 is not defined by the compiler and so it was typedefed to unsigned long by the programmer, but from VC6 onwards UINT32 is defined as unsigned int. This makes my life hard.
My initial reaction was to try replacing all UINT32 in the interface with unsigned long and recompiling. This works as the function signatures are the same. However an unsigned long in 2012 is 64 bits wide... not 32 bits. This is not a problem in most cases but I foresee possible problems with flag parameters and return types.
What I am wondering is if I have missed a more obvious solution for this. I thought of defining a different type
typedef OAM_UINT32 unsigned long //in the library
typedef OAM_UINT32 unsigned int // in my component
But then the problem is going to be the same as what I have already with my two definitions of UINT32... right?
Any help would be much appreciated.
The Problem
Client code
#include <oam_if.h>
....
UINT32 uuid = getSomeLocalUserId();
UINT32 dwOamRetVal = dwOamGetUserDetails( uuid ); // LINK ERROR: Symbol not found
oam_if.h
UINT32 dwOamGetUserDetails( UINT32 idOfUser );
When the library (OAM) is compiled the UINT32 value is evaluated as an unsigned long. When the client component is compiled, UINT32 is evaluated as unsigned int. The linker complains because it has a symbol defined in the OAM library for dwOamGetuserDetails which rakes and returns an unsigned long, but the client is calling a function which according to it should take an unsigned int.
So while their respective inputs are unsigned numbers both 32 bits long, the signature of the function is different and the linker complains.
The only way I can see to fix it is to define everything as unsigned long directly. However then OAM will be using a 32 bit long number but the client will be using a 64 bit number!
Sample of Linker Error
error LNK2001: unresolved external symbol "public: virtual unsigned long __thiscall Message::getCallId(void)const " (?getCallId#Message##UBEKXZ) oam.lib(OAM_SsRequest.obj)
This is actually a callback from the library to the component, so in this case it is looking for a signature that matches UINT32 as defined by the libary (unsigned long) but the component is defining an unsigned int for its callback.

Class declaration in a header file and static variables

Noob question, but would like to understand the following:
Imagine I have a multifile project. I'm specifying a class in a header file to be shared among all the files in the project, and I write this : static int test = 0; and in the next line this: static const int MAX = 4;
The first one would be an error trying to compile because of the one definition rule. But the second one will compile without errors. Why?
From what I understand, both have the same properties: whole execution storage duration, class scope and no linkage.
Any help?
EDIT: testing an external constant declaration in a header: extern const int MAX = 4; to force external linkage produced the expected error. So I don't understand why with the variable it gives me the error and with the constant it doesn't.
Try
static const int test = 0;
I've sometimes noticed compiler errors with the immediate initialization of static const variables in the header file. You can always use the declaration in the header
class MyClass
{
// ...
static const int test;
// ...
}
and initialize it in the corresponding .cpp file
const int MyClass::test = 0;
This should work properly with any other types than int as well.
Integer constants in C++ don't actually occupy any space in the object and don't act like variables in general. Think about them more like numbers that are given names in this particular context.

Getting a compile error with ntddscsi.h

I am having a bit of trouble with the following include:
#include <ntddscsi.h>
When I compile (using NetBean 7.1 & Cygwin C++ compiler), I am told that I need to define "SCSI_PASS_THROUGH" before I can use it... in ntddscsi.h however, it is defined:
typedef struct _SCSI_PASS_THROUGH {
SHORT Length;
CHAR ScsiStatus;
CHAR PathId;
CHAR TargetId;
CHAR Lun;
CHAR CdbLength;
CHAR SenseInfoLength;
CHAR DataIn;
LONG DataTransferLength;
LONG TimeOutValue;
LONG_PTR DataBufferOffset;
LONG SenseInfoOffset;
CHAR Cdb[16];
} SCSI_PASS_THROUGH, *PSCSI_PASS_THROUGH;
Anyone have any idea what on earth is going wrong??
This might happen if you have circular dependencies, or for example LONG_PTR is not defined anywhere.