Hi,

I'm trying to link c object with c++ (using QT Library) object and find the following error.

tonysun:~/tmp# g++ -c main.cpp
tonysun:~/tmp# gcc -c mainlib.c
tonysun:~/tmp# g++ -o main main.o mainlib.o main.cpp:(.text+0x64): undefined reference to `para_prep()' <<main.cpp>>

#include "mainlib.h"
int main(int argc, char *argv[])
{
    para_prep();
    /* Here are code that using QT/C++ library
    */
    return 0;
}

<mainlib.c>

#include "inc.h"
void para_prep()
{
    /* Here are code that using C library only
    */
}

<<mainlib.h>>

void para_prep();

If I remove the QT/C++ code in main.cpp and change main.cpp to main.c and g++ -c main.cpp to gcc -c main.cpp , it will be fine.

How can I link them?

Any suggestion will be appreciated.

I think it's because the calling conventions and object formats in C and C++ are slightly different. So the object file created by gcc is not compatible with the object file created by g++. Possibly something to do with the function name mangling or some-such. I don't have a massive amount of knowledge in this area, but it's certainly some kind of compatibility thing!

So because of the incompatible object formats, when you try to link the two objects to make your executable; I think g++ is unable to resolve the call to para_prep and is showing an error message.

So I guess you have two options here:
1. If mainlib really has to be compiled using gcc, then I suppose you could make mainlib a shared object (.so) and compile/link it with gcc and then use the shared object in your program (just like a .dll in windows programs). In which case you'll need to read up on creating .so's in C and how to use C-based .so's in a C++ program.

OR more simply:

2. You could use g++ to compile and link all three files!
Just because mainlib is written in C doesn't mean you can't use g++ to compile it. After all, any valid C program can also be considered to be a valid C++ program, so g++ should be able to handle it!

So perhaps try this:
g++ -c main.cpp
g++ -c mainlib.c
g++ -o main.o mainlib.o

Which should be far simpler than taking the shared object (.so) route!

C++ does name mangling to ensure method/function names are unique, C does not. So when calling C function from C++ you need to let C++ know it’s a C function. This can be done using the extern "C", read below for examples

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

http://yosefk.com/c++fqa/mixing.html

http://developers.sun.com/solaris/articles/mixing.html

commented: Great post! succinct, accurate and straight to the point! +9

Ah thanks template<>.
I've never had to mix 'pure C' objects with C++ before, so I've never seen that before. I thought there must be another way around it though!
Great post!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.