Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using function written in c++ in c code

Tags:

c++

c

linux

gcc

I am working on a project in which some people have already written code in C++ and we have to use it in our code in C. So I have tried following test to write a test program which demonstrates the same:

The header file is:

 #ifndef h_files_n
    #define h_files_n

    #include<iostream>

    #ifdef __cplusplus
        extern "C" {
    #endif

    void add_func(int, int);

    #ifdef __cplusplus
        }
    #endif

    #endif

cpp file is :

#include"h_files.h"

void add_func(int num, int nums)
{
    std :: cout << "The addition of numbers is : "<< num+nums << std endl;
}

The c file is :

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

int main()
{
    printf("We are calling the C function form C++ file.\n");

    add_func(10,15);

    return 0;
}

makefile is :

CC = gcc
inc = -I include

vpath %.c src
vpath %.cpp src
vpath %.o obj

all : $(addprefix obj/,functions.o main.o) run

run : main.o functions.o
    $(CC) -o bin/$@ $^

obj/%.o : %.cpp
    $(CXX) -c $(inc) $^ -o $@ -libstdc++

obj/%.o : %.c
    $(CC) -c $(inc) $^ -o $@

.PHONY : clean

clean :
    -rm -f obj/* bin/*

I am getting the following error:

g++ -c -I include src/functions.cpp -o obj/functions.o
gcc -c -I include src/main.c -o obj/main.o
gcc -o bin/run obj/main.o obj/functions.o
obj/functions.o: In function `add_func':
functions.cpp:(.text+0x1e): undefined reference to `std::cout'
functions.cpp:(.text+0x23): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)'
functions.cpp:(.text+0x2d): undefined reference to `std::ostream::operator<<(int)'
functions.cpp:(.text+0x32): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)'
functions.cpp:(.text+0x3a): undefined reference to `std::ostream::operator<<(std::ostream& (*)(std::ostream&))'
obj/functions.o: In function `__static_initialization_and_destruction_0(int, int)':
functions.cpp:(.text+0x68): undefined reference to `std::ios_base::Init::Init()'
functions.cpp:(.text+0x77): undefined reference to `std::ios_base::Init::~Init()'
collect2: error: ld returned 1 exit status
make: *** [run] Error 1
  • If I use g++ as linker then It works fine. But gcc linker gives me the problem.
  • As I think of the problem is the function name mangling by g++ and gcc does not mangles the functions name(symbols).
  • So is there any compiler flag that would avoid name mangling if possible.
  • The reason for avoiding g++ linker is It treats the linking as C++ style but the base code is in C so It may introduce some bug in calling code.

Please somebody suggest the solution.

like image 463
Abhijatya Singh Avatar asked Apr 07 '15 17:04

Abhijatya Singh


2 Answers

$(CC) -o bin/$@ $^

Use

run : main.o functions.o
    $(CXX) -o bin/$@ $^

instead to link everything together using the g++ linker, and have the defaults for the linked libstc++.a library set automatically.

Otherwise you'll need to specify -lstc++ as additional library explicitely.


Also if you're designing a pure c-API for your c++ code you should have the

 #include <iostream>

statement in the functions.cpp source file only. Remove c++ standard headers from functions.h.


Please don't use using namespace std; in c++ header files generally. It's prone to invoke namespace clashes of all unexpected kinds (no one knows about all of the names used in the namespace std).

It should not appear in a pure c-API header file anyway.


If you want to have a mixed c/c++ API header file, put all of the c++ specific statements within the c++ guards:

 #ifdef __cplusplus
 #include<iostream>

 class xyz; // A c++ forward declaration
 #endif
like image 126
πάντα ῥεῖ Avatar answered Oct 19 '22 06:10

πάντα ῥεῖ


You should either link program by g++ or manually specify libstdc++ library(ies).

like image 24
Slava Avatar answered Oct 19 '22 04:10

Slava