Reputation: 109
I had been trying to link a cpp script to a c file using g++ compiler. But I keep getting global var in .c file declared as double definations.
.cpp
extern "C"
{
#include "cFile.h"
}
Below is my method of compiling the 2 files.
g++ -c -o cFile.o cFile.c
g++ -c -o cppFile.o cppFile.cpp
g++ -o ExeFile cFile.o cppFile.o
Below is my error message.
cFile.o:(.bss+0x0): multiple definition of `NoOfRecordsRead'
cppFile.o:(.bss+0x0): first defined here
cFile.o:(.bss+0x20): multiple definition of `globalCountryDataArray'
cppFile.o:(.bss+0x20): first defined here
collect2: error: ld returned 1 exit status
Please help. Thanks in advance!
Below is my raw header file as requested.
#ifndef COUNTRY_DATA_H
#define COUNTRY_DATA_H
// ====================================================================
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
// ====================================================================
#define TLD_LEN 2
#define COUNTRY_LEN 100
#define FIPS104_LEN 2
#define ISO2_LEN 2
#define ISO3_LEN 3
#define CAPITAL_LEN 100
#define REGION_LEN 100
#define CURRENCY_LEN 50
#define CURRENCY_CODE_LEN 3
#define No_Of_Rec_Fields 11
#define Max_Record_Size 250
#define Line_Char_Buffer_Size 400
#define LINE_DATA_DELIMITER ","
#define INPUT_FILE_NAME "Countries.txt"
// ===================================================================
//const char* LINE_DATA_DELIMITER = ",";
//const char* INPUT_FILE_NAME = "Countries.txt";
typedef struct CountryRecord
{
char TLD [TLD_LEN+1]; // Top Level Domain code
char Country [COUNTRY_LEN+1];
char FIPS104 [FIPS104_LEN+1]; // Ctry code according to FIPS104 standard
char ISO2 [ISO2_LEN+1]; // Ctry code according to ISO2 standard
char ISO3 [ISO3_LEN+1]; // Ctry code according to ISO3 standard
double ISONo;
char Capital [CAPITAL_LEN+1];
char Region [REGION_LEN+1]; // E.g. Asia, Europe, etc.
char Currency [CURRENCY_LEN+1]; // Full name of currency
char CurrencyCode [CURRENCY_CODE_LEN+1]; // Currency abbreviation
double Population;
} CountryRecordType;
int NoOfRecordsRead;
CountryRecordType globalCountryDataArray [Max_Record_Size];
// ====================================================================
void readData ();
char* get_line (char *s, size_t n, FILE *f);
CountryRecordType createCountryRecord (char* aLine);
void displayRecordContent (CountryRecordType ctryRec);
void showAllRecords ();
int findCountryRecord (const char* countryName);
char* getCapital (const char* countryName);
char* getCurrencyCode (const char* countryName);
// ====================================================================
#endif // COUNTRY_DATA_H
Upvotes: 0
Views: 133
Reputation: 109
By combined solutions provided by hyde and FroggyDay. I created a .h for my cpp file and then copied placed my
extern "C"
{
#include "CountryData.h"
}
into the cppFile.h along with other codes from my .cpp file.
I then followed hyde's solution to place extern for global variables in my c header
extern int NoOfRecordsRead;
extern CountryRecordType globalCountryDataArray [Max_Record_Size];
Finally, declaring the varibles in my c file.
int NoOfRecordsRead;
CountryRecordType globalCountryDataArray [Max_Record_Size];
I then can compile my script successfully.
Upvotes: 0
Reputation: 62898
This line in your cFile.h file, the line int NoOfRecordsRead;
should be:
extern int NoOfRecordsRead; // declare that this variable is defined somewhere
Then, in your cFile.c, you should have
int NoOfRecordsRead; // define this variable in exactly one place
What is problem in your current code is, you define a global variable in a .h file. So it gets defined in every .o file, where that .h file is included in compilation. And linker does not like multiple definitions like that. Only define stuff in .c / .cpp files which get compiled only once, to one .o file.
Upvotes: 3
Reputation: 121819
1) I would put extern "C" {...}
INSIDE your header, not outside.
2) The problem is, I would put extern int NoOfRecordsRead;
in your header.
Then actually declare "NoOfRecordsRead" in one ... and only one ... C or C++ module.
3) Do the same for ountryRecordType globalCountryDataArray[]
as well.
Upvotes: 2