nubbear
nubbear

Reputation: 109

Unable to link C++ with C object

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

Answers (3)

nubbear
nubbear

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

hyde
hyde

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

paulsm4
paulsm4

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

Related Questions