4

I have a function in C++ that uses data types like vector and map from STL. Here is some sample code:

mylib.cpp

#include "mylib.h"
#include<vector>
using namespace std;

    int summation(int n) {
    vector<int> numbers;
    int sum = 0;
    for(int i = 1; i <=n; i++) 
        numbers.push_back(i);
    for(int j = 0; j < numbers.size(); j++)
        sum += numbers[j];

    return sum;
    }

I created a header file as follows:

mylib.h

#ifdef _cplusplus
extern "C" {
#endif
extern int summation(int n);
#ifdef _cplusplus
};
#endif

The C++ file was compiled into the obejct code using the command

g++ -o mylib.o -c mylib.cpp

Then, I wrote a C program in order to use the function summation from it.

main.c

#include<stdio.h>
#include "mylib.h"

int main() {
    int n;
    scanf("%d", &n);
    printf("%d", summation(n));
    return 0;
}

Now, when I compile the C file above using gcc,

gcc main.c mylib.o

I get the following error

/tmp/ccAMN2ld.o: In function `main':
main.c:(.text+0x33): undefined reference to `summation'
mylib.o: In function `std::vector<int, std::allocator<int> >::_M_insert_aux(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, int const&)':
mylib.cpp:(.text._ZNSt6vectorIiSaIiEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPiS1_EERKi[_ZNSt6vectorIiSaIiEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPiS1_EERKi]+0x26e): undefined reference to `__cxa_begin_catch'
mylib.cpp:(.text._ZNSt6vectorIiSaIiEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPiS1_EERKi[_ZNSt6vectorIiSaIiEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPiS1_EERKi]+0x2d7): undefined reference to `__cxa_rethrow'
mylib.cpp:(.text._ZNSt6vectorIiSaIiEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPiS1_EERKi[_ZNSt6vectorIiSaIiEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPiS1_EERKi]+0x2df): undefined reference to `__cxa_end_catch'
mylib.o: In function `std::vector<int, std::allocator<int> >::_M_check_len(unsigned long, char const*) const':
mylib.cpp:(.text._ZNKSt6vectorIiSaIiEE12_M_check_lenEmPKc[_ZNKSt6vectorIiSaIiEE12_M_check_lenEmPKc]+0x5b): undefined reference to `std::__throw_length_error(char const*)'
mylib.o: In function `__gnu_cxx::new_allocator<int>::deallocate(int*, unsigned long)':
mylib.cpp:(.text._ZN9__gnu_cxx13new_allocatorIiE10deallocateEPim[_ZN9__gnu_cxx13new_allocatorIiE10deallocateEPim]+0x1c): undefined reference to `operator delete(void*)'
mylib.o: In function `__gnu_cxx::new_allocator<int>::allocate(unsigned long, void const*)':
mylib.cpp:(.text._ZN9__gnu_cxx13new_allocatorIiE8allocateEmPKv[_ZN9__gnu_cxx13new_allocatorIiE8allocateEmPKv]+0x2c): undefined reference to `std::__throw_bad_alloc()'
mylib.cpp:(.text._ZN9__gnu_cxx13new_allocatorIiE8allocateEmPKv[_ZN9__gnu_cxx13new_allocatorIiE8allocateEmPKv]+0x3c): undefined reference to `operator new(unsigned long)'
mylib.o:(.eh_frame+0x4b): undefined reference to `__gxx_personality_v0'
collect2: error: ld returned 1 exit status

It is imperative that I use gcc to compile the C file. Is there a way to make it work?

I tried looking for solution and stumbled upon the links below,

How to call C++ function from C?

Elegantly call C++ from C

http://www.cplusplus.com/forum/general/8997/

but couldn't find a solution to my problem.

Community
  • 1
  • 1
Saqib Shamsi
  • 522
  • 6
  • 15
  • 1
    Why would a c compiler know how to compile c++ components. Maybe you need to compile the c++ component fully then link the binaries. – marshal craft Dec 28 '16 at 05:22
  • This question looks like a dupe of those you linked to. The answers describe general possible solutions, and you need to implement them in your concrete code, that's all. – ForceBru Dec 28 '16 at 05:22
  • 4
    Use `g++` to link the code (not `gcc` — the program is a C++ program because it has some C++ in it). It is usually better to use `g++` to compile the file containing `main()` since that has special properties in C++ (unlike in C), though you may get away with using a C compiler to create the object file holding `main()`. – Jonathan Leffler Dec 28 '16 at 05:22
  • @ForceBru In those questions, STL components haven't been used. I got the error I mentioned when I tried those approaches. However, it worked for programs that don't contain STL components but not for the ones containing them. – Saqib Shamsi Dec 28 '16 at 05:29
  • @JonathanLeffler Compiling with `g++` works. However, as I mentioned that it is really important that I use `gcc` for the file containing the `main` function. I was hoping there was a way around. – Saqib Shamsi Dec 28 '16 at 05:31
  • 1
    You can try compiling `main.c` to `main.o` with `gcc`, then linking with `g++ -o program main.o mylib.o` — you may be lucky and get away with that. Failing that, create `cpp-main.cpp` containing `extern "C" int c_main(); int main() { return c_main(); }` (or `extern "C" int c_main(int argc, char **argv); int main(int argc, char **argv) { return c_main(argc, argv); }`) and compile that with `g++`. In the existing `main.c`, change the function to `int c_main(void) { …your code… }` (or the equivalent with arguments), not forgetting to declare the function (since it is no longer called `main()`). – Jonathan Leffler Dec 28 '16 at 05:42
  • 5
    The crucial point is to link the program with `g++` so that you get the correct C++ libraries linked. Linking with `gcc` will be a painful exercise by comparison. In case of doubt, try using `g++ -v` and `gcc -v` to do the different linking operations, and see how much difference there is in the commands invoked to do the linking. – Jonathan Leffler Dec 28 '16 at 05:45
  • This is same question. Maybe help you. [See here](http://stackoverflow.com/questions/11580968/c-and-c-linkage-with-extern-c) – saeid zamani Dec 28 '16 at 06:28
  • You need to use `extern "C"` in `mylib.h` **and** the `mylib.cpp` file. Also link against the `C++` runtime library `-lstdc++` (I think) – Galik Dec 28 '16 at 06:52
  • This answer should help: https://stackoverflow.com/questions/31903005/how-to-mix-c-and-c-correctly/31903685#31903685 – Galik Dec 28 '16 at 06:57
  • In fact possible duplicate of https://stackoverflow.com/questions/31903005/how-to-mix-c-and-c-correctly – Galik Dec 28 '16 at 06:58

2 Answers2

2

Compile the C file by itself with the C compiler:

gcc -c cfile.c

then link all the files with the C++ compiler:

g++ -o a.out main.o cfile.o mylib.o

Note that you must compile the file with the main function with the C++ compiler. Any other files can be compiled with either, though you need extern "C" declarations to be able to call C code from C++ or create C++ functions that can be called from C

Chris Dodd
  • 119,907
  • 13
  • 134
  • 226
0

I have build all the file in g++, am not getting linking error. can you build all the source file to gcc or g++.

Jitendra
  • 11
  • 2