linking C object file to C++ object file on linux

Mar 20, 2009 at 10:29pm
Hi,
this is my problem: I have two file in C,one of this have .c extenction and I have compile it with gcc to obtain an object file .This file explain what function (included in another file)do. the other one have .h extection,and contain jast the name of some function that are explain in the previous file, with .c extenction. so, this two file contain some libraries that a C++ file can't read. At this point I have wrote a c++ file that include the file with .h extention in order to use the function defined with c file, and the idea is that this file .h is see like a library. I have complile this c++ file with g++. now I have to link the object file obtain by C file with the object file obtain with C++ file. how can I do this?
thanks!
Mar 20, 2009 at 11:09pm
If you compile with a C compiler, then the header file needs to have

extern "C" {
}

around the declarations. Then you should be able to link with no problems.

Alternatively, since you have the source code, if possible, compile all code with the C++ compiler and forget the extern "C".
Mar 23, 2009 at 2:43pm
I have done as you tell me...but the problem still remain. in the c++ file I have write(myprogram.c)
#include<.....>
#include<....>
extern "C" {
#include "file.h"
}
int main(){

here I have use the function explain in C file
}
then I have compile it with g++.

I have write the .h file in this way

#ifdef _cplusplus
extern "C" {
#endif
struct indirizzo{
unsigned int ips;
unsigned int ipd;
unsigned int sPort;
unsigned int dPort;
unsigned int protocol;
unsigned int fid;
unsigned int ipsmasks;
unsigned int ipdmaskd;
};




int ValidateFunc(const char *buffer, int length, int socket);
struct indirizzo * parseDoc(char* buffer, int dim);
const char *XmlwriterMemory1(const char *file);
const char *XmlwriterMemory2(const char *file);
#ifdef _cplusplus
}
# endif

this is my file.h

in the last C file(myfile.c) I have explain what this function do.
then I have compile this with gcc.

now I write on terminal
g++ -o myfile.o myprogram.o

the terminal still say that it don't find function parseDoc(), XmlwriterMemory1(), XmlwriterMemory2() and ValidataFunc() in the main()

what else is wrong?
thanks
Mar 23, 2009 at 3:47pm
You are missing a command-line parameter on the link step.

g++ -o myprogram myfile.o myprogram.o

Your command line is trying to link myprogram.o to an executable named myfile.o
Mar 23, 2009 at 4:56pm
sorry! but it don't work. if I do like you say, I have new errors.it don't recognize the library (and the variable )of the C program, the one in which I have explain what function do.... I must modify something in the .c file?
Mar 24, 2009 at 10:46am
I'll try to explain batter my problem:
I have 3 file. 2 are write in C and one in C++. one in C have .h extension and it is (myfile.h)
#ifdef _cplusplus
extern "C" {
#endif
struct indirizzo{
unsigned int ips;
unsigned int ipd;
unsigned int sPort;
unsigned int dPort;
unsigned int protocol;
unsigned int fid;
unsigned int ipsmasks;
unsigned int ipdmaskd;
};




int ValidateFunc(const char *buffer, int length, int socket);
struct indirizzo * parseDoc(char* buffer, int dim);
const char *XmlwriterMemory1(const char *file);
const char *XmlwriterMemory2(const char *file);
#ifdef _cplusplus
}
# endif

the other one have .c extension and the form is (myfile.c)

#include <stdio.h>
#include <string.h>
#include <libxml2/libxml/encoding.h>
#include <libxml2/libxml/xmlwriter.h>
#include <stdlib.h>
#include <libxml2/libxml/xmlmemory.h>
#include <libxml2/libxml/parser.h>
#include <libxml2/libxml/tree.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <errno.h>

#include "myfile.h"

const char *XmlwriterMemory2(const char *file){ here I make my program}
const char *XmlwriterMemory1(const char *file){.......}

int
ValidateFunc(const char *buffer, int length, int socket) {........}

struct indirizzo*
getReference (xmlDocPtr doc, xmlNodePtr cur) {.............}

void
parseStory (xmlDocPtr doc, xmlNodePtr cur) {........}

struct indirizzo*
parseDoc(char* buffer, int dim) {........}

then I write a C++ file in this way(myprogram.c)

#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <errno.h>
#include <list>
#include <vector>

extern "C"{
#include "myfile.h"
}

using namespace std;

#define MY_ENCODING "ISO-8859-1"



class EEE {
public:
unsigned int ips;
unsigned int ipd;
unsigned int sPort;
unsigned int dPort;
unsigned int protocol;
unsigned int fid;
unsigned int ipsmasks;
unsigned int ipdmaskd;

list<int> id ;
};

int
main (int argc, char **argv)
{........
...........
...............
val=ValidateFunc(srv_buf, 1024, socket);
.........................
......................
prima_info = parseDoc (srv_buf, 1024);
.................
............................
......................
char *mes1 = (char *) XmlwriterMemory2("messaggio2.xml");
........
}

now I compile in this way
gcc -c -I/usr/include/lixml2 myfile.c
and everything is ok
g++ -c myprogram.c
and it's ok

g++ -o myprogram myfile.o myprogram.o

now I have some errors like this:
myfile.o: In function `parseDoc':
myfile.c:(.text+0xcf8): undefined reference to `xmlParseMemory'
(and other eror for other variable. I have this kind of error in each 4 function I have define)

myprogram.o: In function `main':
myprogram.c:(.text+0x257): undefined reference to `ValidateFunc(char const*, int, int)'
(the same for the other 3 functions)

I really don't know where problem is, and I'm really desperated because I can't go on with my work!
thanks






Mar 24, 2009 at 12:18pm
Do an

objdump -ax myprogram.o
objdump -ax myfile.o

and post results.
Mar 24, 2009 at 2:19pm
First of all I want to say thank you for help me.
now I have wrote the command you say to me and the result are:
for myfile.o (look myxml2 is the file that I have indicated with myfile)

myxml2.o: file format elf32-i386
myxml2.o
architecture: i386, flags 0x00000011:
HAS_RELOC, HAS_SYMS
start address 0x00000000

Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000e04 00000000 00000000 00000034 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
1 .data 00000000 00000000 00000000 00000e38 2**2
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000000 00000000 00000000 00000e38 2**2
ALLOC
3 .rodata 000004ab 00000000 00000000 00000e38 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .comment 00000025 00000000 00000000 000012e3 2**0
CONTENTS, READONLY
5 .note.GNU-stack 00000000 00000000 00000000 00001308 2**0
CONTENTS, READONLY
SYMBOL TABLE:
00000000 l df *ABS* 00000000 myxml2.c
00000000 l d .text 00000000 .text
00000000 l d .data 00000000 .data
00000000 l d .bss 00000000 .bss
00000000 l d .rodata 00000000 .rodata
00000000 l d .note.GNU-stack 00000000 .note.GNU-stack
00000000 l d .comment 00000000 .comment
00000000 g F .text 000001a6 XmlwriterMemory2
00000000 *UND* 00000000 xmlBufferCreate
00000000 *UND* 00000000 puts
00000000 *UND* 00000000 xmlNewTextWriterMemory
00000000 *UND* 00000000 xmlTextWriterStartDocument
00000000 *UND* 00000000 xmlTextWriterStartElement
00000000 *UND* 00000000 xmlTextWriterWriteElement
00000000 *UND* 00000000 xmlTextWriterEndElement
00000000 *UND* 00000000 xmlTextWriterEndDocument
00000000 *UND* 00000000 xmlFreeTextWriter
00000000 *UND* 00000000 fopen
00000000 *UND* 00000000 fputs
00000000 *UND* 00000000 fclose
.....................................
.....................................
....................................
RELOCATION RECORDS FOR [.text]:
OFFSET TYPE VALUE
00000007 R_386_PC32 xmlBufferCreate
00000017 R_386_32 .rodata
0000001c R_386_PC32 puts
00000034 R_386_PC32 xmlNewTextWriterMemory
00000044 R_386_32 .rodata
00000049 R_386_PC32 puts
0000005e R_386_32 .rodata
00000071 R_386_PC32 xmlTextWriterStartDocument
00000081 R_386_32 .rodata
00000086 R_386_PC32 puts
00000090 R_386_32 .rodata
0000009f R_386_PC32 xmlTextWriterStartElement
000000af R_386_32 .rodata
...................................
............................
...............................
00000d36 R_386_PC32 xmlDocGetRootElement
00000d44 R_386_32 stderr
00000d5f R_386_32 .rodata
00000d64 R_386_PC32 fwrite
00000d6f R_386_PC32 xmlFreeDoc
00000d79 R_386_32 .rodata
00000d8b R_386_PC32 xmlStrcmp
00000d94 R_386_32 stderr
00000daf R_386_32 .rodata
00000db4 R_386_PC32 fwrite
00000dbf R_386_PC32 xmlFreeDoc
00000dd3 R_386_PC32 getReference
00000de8 R_386_PC32 parseStory
00000df3 R_386_PC32 xmlFreeDoc

instead for the c++ file mioprogramma.o I obtain:

00000534 R_386_PC32 _ZNSt4listIiSaIiEED1Ev
0000054b R_386_PC32 __stack_chk_fail


RELOCATION RECORDS FOR [.text._ZNSaISt10_List_nodeIiEED1Ev]:
OFFSET TYPE VALUE
0000000d R_386_PC32 _ZN9__gnu_cxx13new_allocatorISt10_List_nodeIiEED2Ev


RELOCATION RECORDS FOR [.text._ZNSaISt10_List_nodeIiEED2Ev]:
OFFSET TYPE VALUE
0000000d R_386_PC32 _ZN9__gnu_cxx13new_allocatorISt10_List_nodeIiEED2Ev
.......................................
.......................................
.....................................
RELOCATION RECORDS FOR [.text._ZNSt4listIiSaIiEE5eraseESt14_List_iteratorIiES3_]:
OFFSET TYPE VALUE
0000001d R_386_PC32 _ZNSt4listIiSaIiEE5eraseESt14_List_iteratorIiE
00000038 R_386_PC32 _ZNKSt14_List_iteratorIiEneERKS0_


RELOCATION RECORDS FOR [.text._ZNSt10_List_baseIiSaIiEE8_M_clearEv]:
OFFSET TYPE VALUE
00000033 R_386_PC32 _ZNKSt10_List_baseIiSaIiEE19_M_get_Tp_allocatorEv
00000045 R_386_PC32 _ZN9__gnu_cxx13new_allocatorIiE7destroyEPi
00000050 R_386_PC32 _ZNSaIiED1Ev
00000062 R_386_PC32 _ZNSt10_List_baseIiSaIiEE11_M_put_nodeEPSt10_List_nodeIiE
...........................................
.........................................
..........................................
RELOCATION RECORDS FOR [.text._ZNSt4listIiSaIiEE6insertISt20_List_const_iteratorIiEEEvSt14_List_iteratorIiET_S7_]:
OFFSET TYPE VALUE
0000000f R_386_PC32 _ZNSt10_List_baseIiSaIiEE21_M_get_Node_allocatorEv
0000001e R_386_PC32 _ZNSaIiEC1ISt10_List_nodeIiEEERKSaIT_E
0000003e R_386_PC32 _ZNSt4listIiSaIiEEC1ISt20_List_const_iteratorIiEEET_S5_RKS0_
0000004f R_386_PC32 _ZNSaIiED1Ev
00000068 R_386_PC32 _ZNSt4listIiSaIiEE6spliceESt14_List_iteratorIiERS1_
00000087 R_386_PC32 _ZNSaIiED1Ev
00000098 R_386_PC32 _Unwind_Resume
000000a3 R_386_PC32 _ZNSt4listIiSaIiEED1Ev
000000c1 R_386_PC32 _ZNSt4listIiSaIiEED1Ev
000000d2 R_386_PC32 _Unwind_Resume
...............................
...................................
...............................
RELOCATION RECORDS FOR [.eh_frame]:
OFFSET TYPE VALUE
00000012 R_386_32 __gxx_personality_v0
00000024 R_386_32 .text._ZNSt4listIiSaIiEE8_M_eraseESt14_List_iteratorIiE
00000044 R_386_32 .text._ZNSt4listIiSaIiEE5eraseESt14_List_iteratorIiE
00000064 R_386_32 .text._ZNSt4listIiSaIiEE5eraseESt14_List_iteratorIiES3_
00000084 R_386_32 .text._ZN9__gnu_cxx13new_allocatorISt10_List_nodeIiEE8allocateEjPKv
000000a4 R_386_32 .text._ZNSt10_List_baseIiSaIiEE11_M_get_nodeEv
000000c4 R_386_32 .text._ZNSt4listIiSaIiEE14_M_create_nodeERKi
000000e4 R_386_32 .text._ZNSt4listIiSaIiEE9_M_insertESt14_List_iteratorIiERKi
00000104 R_386_32 .text._ZNSt4listIiSaIiEE9push_backERKi
00000124 R_386_32 .text._ZNSt4listIiSaIiEE22_M_initialize_dispatchISt20_List_const_iteratorIiEEEvT_S5_St12__false_type
00000144 R_386_32 .text._ZNSt4listIiSaIiEEC1ISt20_List_const_iteratorIiEEET_S5_RKS0_
0000014d R_386_32 .gcc_except_table
00000168 R_386_32 .text._ZNSt4listIiSaIiEEC1ERKS1_
00000171 R_386_32 .gcc_except_table
0000018c R_386_32 .text._ZN3EEEC1ERKS_
000001ac R_386_32 .text._ZN9__gnu_cxx13new_allocatorI3EEEE9constructEPS1_RKS1_
000001b5 R_386_32 .gcc_except_table
000001d0 R_386_32 .text._ZN9__gnu_cxx13new_allocatorISt10_List_nodeI3EEEEE8allocateEjPKv
000001f0 R_386_32 .text._ZNSt10_List_baseI3EEESaIS0_EE11_M_get_nodeEv
00000210 R_386_32 .text._ZNSt4listI3EEESaIS0_EE14_M_create_nodeERKS0_
00000219 R_386_32 .gcc_except_table
00000234 R_386_32 .text._ZNSt4listI3EEESaIS0_EE9_M_insertESt14_List_iteratorIS0_ERKS0_
00000254 R_386_32 .text._ZNSt4listI3EEESaIS0_EE10push_frontERKS0_
00000274 R_386_32 .text._ZNSt4listIiSaIiEE25_M_check_equal_allocatorsERS1_
00000294 R_386_32 .text._ZNSt4listIiSaIiEE11_M_transferESt14_List_iteratorIiES3_S3_
000002b4 R_386_32 .text._ZNSt4listIiSaIiEE6spliceESt14_List_iteratorIiERS1_
000002d4 R_386_32 .text._ZNSt4listIiSaIiEE6insertISt20_List_const_iteratorIiEEEvSt14_List_iteratorIiET_S7_
000002dd R_386_32 .gcc_except_table
000002f8 R_386_32 .text._ZNSt4listIiSaIiEEaSERKS1_
00000318 R_386_32 .text
00000321 R_386_32 .gcc_except_table


I don't know the meaning of all this things.....


Mar 24, 2009 at 3:05pm
I forgot one thing: I'm using a c++ compiler , or better, when I link the two object file I use g++.
to compile c++ file I use g++ and to complile c file I use gcc. I specify this because at the beginning you tell me "If you compile with a C compiler,". I don't know if this information is useful.
Mar 24, 2009 at 4:56pm
I have resolve the problem!
the file .h must be

extern "C" {

struct indirizzo{
unsigned int ips;
unsigned int ipd;
unsigned int sPort;
unsigned int dPort;
unsigned int protocol;
unsigned int fid;
unsigned int ipsmasks;
unsigned int ipdmaskd;
};




extern int ValidateFunc(const char *buffer, int length, int socket);
extern struct indirizzo * parseDoc(char* buffer, int dim);

extern const char *XmlwriterMemory1(const char *file);
extern const char *XmlwriterMemory2(const char *file);
}

and in the C++ file don't need extern "c"{
#include "myxml1.h"
}
but jest
#include "myxml1.h"

then

g++ -o out.e -lxml2 myxml2.o mioprogramma.o

bye
Mar 27, 2009 at 10:01am
sorry! the previous solution is wrong! this is the right version:

the file .h must be

#ifdef _cplusplus
extern "C" {
#endif
struct indirizzo{
unsigned int ips;
unsigned int ipd;
unsigned int sPort;
unsigned int dPort;
unsigned int protocol;
unsigned int fid;
unsigned int ipsmasks;
unsigned int ipdmaskd;
};




extern int ValidateFunc(const char *buffer, int length, int socket);
extern struct indirizzo * parseDoc(char* buffer, int dim);
extern const char *XmlwriterMemory1(const char *file);
extern const char *XmlwriterMemory2(const char *file);
#ifdef _cplusplus
}
# endif


and in the C++ file we must write :
extern "c"{
#include "myxml1.h"
}

then
g++ -o out.exe -lxml2 myxml2.o mioprogramma.o


Bye!!
Topic archived. No new replies allowed.