Solved

Linking in UNIX

Posted on 2004-08-23
13
244 Views
Last Modified: 2010-04-15
Hello,

I use g++ (most of the program is written in C, but a couple of files are written in C++). I usually use a makefile to build the project. Now I have a problem: all the .o are build ok, but the linkage fails. That's what I get:

g++ -Wall PerformDbTask.o Parse.o MyStr.o DateTime.o Main.o Ini.o LinkedList.o Memory.o DataManagement.o -o Main
PerformDbTask.o: In function `PerformDropTable(DB *, first_node *, string *)':
PerformDbTask.o(.text+0x111): undefined reference to `IniReadInt(first_node *, char *, char *, int)'
PerformDbTask.o(.text+0x17d): undefined reference to `IniReadStr(first_node *, char *, char *, char *)'
DataManagement.o: In function `FieldInit(Field **, first_node *, int)':
DataManagement.o(.text+0x301): undefined reference to `IniReadStr(first_node *, char *, char *, char *)'
etc.........................................

IniReadInt, IniReadStr are all in Ini.c (& .h & .o), which was successfully built, and I compile with Ini.o. So I cannot see where the problem is (of course, I included Ini.h in PerformDbTask).

Any suggestions?
0
Comment
Question by:slavikn
  • 8
  • 3
13 Comments
 
LVL 23

Expert Comment

by:brettmjohnson
ID: 11875991
I suspect that PerformDbTask and DataManagement are C++ files and you are running into
C++ name-mangling difficulties when linking with the objects generated from the C files.

I make the assumption that the C files have 1 or more header files (.h) that describe the
interfaces to the C functions.
The solution is to either:

1) In the C++ files, around the #include for C headers, do

extern "C" {
#include "myCheader.h"
#include "myOtherCheader.h"
}


2) Protect the C header files themselves, by surrounding the entire contents with extern "C".
(This is how the system header files are constructed.):

/* put this at the top */
#ifdef __cplusplus
extern "C" {
#endif

/* and this at the bottom */
#ifdef __cplusplus
}  /* close extern "C" */
#endif

0
 
LVL 1

Author Comment

by:slavikn
ID: 11876076
Only "MyStr.cpp" is C++. All the other files are pure C.
I don't have functions with same names.

I tried to put "extern "C" {", so that in DataManagement.h I have:

extern "C" {
#include "MyAssert.h"
#include "Memory.h"
#include "LinkedList.h"
#include "Ini.h"
#include "DataBase.h"
}
#include "MyStr.h"

(also tried:
extern "C" {
#include "MyAssert.h"
#include "Memory.h"
#include "LinkedList.h"
#include "Ini.h"
#include "DataBase.h"
#include "MyStr.h"
}
)

but when I compile, I still get an error (a different one this time):

g++ -Wall -c DataManagement.c
In file included from DataBase.h:4,
                 from DataManagement.h:9,
                 from DataManagement.c:1:
MyStr.h:27: parse error before `&'
MyStr.h:29: parse error before `&'
MyStr.h:32: parse error before `&'
MyStr.h:38: syntax error before `operator'
MyStr.h:39: syntax error before `operator'
MyStr.h:53: parse error before `&'
MyStr.h:54: parse error before `&'
MyStr.h:54: `string::FindStr(...)' has already been declared in `string'
MyStr.h:55: parse error before `&'
etc..........

Any clues ple-e-e-ease?
0
 
LVL 23

Expert Comment

by:brettmjohnson
ID: 11876848
You must only include the C header files in extern "C", not the C++ header files.
And you cannot include C++ header files from within the C header files.





0
Back Up Your Microsoft Windows Server®

Back up all your Microsoft Windows Server – on-premises, in remote locations, in private and hybrid clouds. Your entire Windows Server will be backed up in one easy step with patented, block-level disk imaging. We achieve RTOs (recovery time objectives) as low as 15 seconds.

 
LVL 1

Author Comment

by:slavikn
ID: 11878857
In all my .h files I added "extern "C" {" before all the "include"s of C files, and only MyStr.h is not in thie block. But I still have problems:

nova 89% make -f MakeMain
g++ -Wall -c PerformDbTask.c
In file included from DataBase.h:4,
                 from PerformDbTask.h:8,
                 from PerformDbTask.c:1:
MyStr.h:29: parse error before `&'
MyStr.h:31: parse error before `&'
MyStr.h:34: parse error before `&'
MyStr.h:40: syntax error before `operator'
MyStr.h:41: syntax error before `operator'
etc...

Maybe I should also put "extern "C" {" into my ".c" files? (for example in "DateTime.c" something like:

extern "C" {
   DateTime.h
}

Doesn't make sense......

----------------------------------------------

I'll return to:

In file included from DataBase.h:4,
                 from PerformDbTask.h:8,
                 from PerformDbTask.c:1:

Here are the includes in DateBase.h

#include "MyStr.h"

Here are the includes in PerformDbTask.h

extern "C" {
#include "MyAssert.h"
#include "Memory.h"
#include "Ini.h"
#include "DataBase.h"
#include "DataManagement.h"
}
#include "MyStr.h"

Here are the includes in PerformDbTask.c

#include "PerformDbTask.h"

-----------------------------------------

I've increased points to 150.
0
 
LVL 23

Expert Comment

by:brettmjohnson
ID: 11879058
It looks like you are #including (indirectly via PerformDbTask.h) a C++ header file into a C file.
The compiler thinks it is compiling ANSI C code, but encounters C++ constructs and barfs.

Using extern "C" allows the use in C++ programs header files and libraries that are intended
to be used by ANSI-C programs.  It avoids C++ name-mangling for the C symbols.  However,
it is not so easy to go the other direction (C referencing C++).  You might be better off removing
the extern "C" mechanism for your local C header files and compile everything as C++ using
the " -x c++ " switch to g++.

0
 
LVL 1

Author Comment

by:slavikn
ID: 11879136
No... it doesn't help........
0
 
LVL 1

Author Comment

by:slavikn
ID: 11879186
Maybe this will help:

The following command works:
nova 34% g++ -Wall Parse.o MyStr.o DateTime.o TestParse.o Ini.o LinkedList.o Memory.o -o TestParse
As you can see, it also uses MyStr.cpp, and works perfectly well.

If I want to compile Main.c and DataManagement.c instead of TestParse.c, so that I have:
nova 35% g++ -Wall Parse.o MyStr.o DateTime.o Main.o DataManagement.o Ini.o LinkedList.o Memory.o -o TestParse
I get all these errors:

Main.o: In function `main':
Main.o(.text+0x4c8): undefined reference to `PerformCreateTable(DB *, first_node *, string *)'
DataManagement.o: In function `FieldInit(Field **, first_node *, int)':
DataManagement.o(.text+0x301): undefined reference to `IniReadStr(first_node *, char *, char *, char *)'
DataManagement.o(.text+0x35d): undefined reference to `IniReadInt(first_node *, char *, char *, int)'
DataManagement.o(.text+0x38d): undefined reference to `IniReadStr(first_node *, char *, char *, char *)'
D
etc........
0
 
LVL 1

Author Comment

by:slavikn
ID: 11887347
I'm increasing points to 370 (and won't increase more :-()
PLEASE HELP ! IT'S VERY IMPORTANT  :-(((
0
 
LVL 1

Author Comment

by:slavikn
ID: 11887559
Please don't post in this thread.
Post on http://www.experts-exchange.com/Programming/Programming_Languages/C/Q_21105991.html instead. I'll give the points there (and will ask the moderators to reward me for this one, as it wasn't answered.)
0
 
LVL 1

Author Comment

by:slavikn
ID: 11897561
The problem was solved.
I just had to remove all my old .o files.
Don't know why "clean" didn't do the job...
Thanks anyway.
0
 
LVL 1

Author Comment

by:slavikn
ID: 11897581
Stupid me... I didn't include all .o files in the "clean" clause in the makefile...  :'-(
0
 

Accepted Solution

by:
ee_ai_construct earned 0 total points
ID: 11933754
Closed, 370 points refunded.
ee_ai_construct (replacement part #xm34)
Community Support Moderator
0

Featured Post

Complete VMware vSphere® ESX(i) & Hyper-V Backup

Capture your entire system, including the host, with patented disk imaging integrated with VMware VADP / Microsoft VSS and RCT. RTOs is as low as 15 seconds with Acronis Active Restore™. You can enjoy unlimited P2V/V2V migrations from any source (even from a different hypervisor)

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

An Outlet in Cocoa is a persistent reference to a GUI control; it connects a property (a variable) to a control.  For example, it is common to create an Outlet for the text field GUI control and change the text that appears in this field via that Ou…
Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
The goal of this video is to provide viewers with basic examples to understand and use structures in the C programming language.
The goal of this video is to provide viewers with basic examples to understand opening and reading files in the C programming language.

829 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question