Include and compile C++ header file from C - c++

I have a C++ file and its header file. I need to include this header file in a C code and use the functions in it.
When the cpp.h file is compiled through main.c, compilation fails because of the C++ linkage.
On using the macro __cplusplus stream and string are not resolved, is there some way to compile the cpp.h file through and execute?
I have given a outline of my code only.
C++ header file cpp.h:
struct s1
{
string a;
string b;
};
typedef struct s1 s2;
class c1
{
public:
void fun1(s2 &s3);
private:
fun2(std::string &x,const char *y);
};
C++ file cpp.cpp:
c1::fun1(s2 &s3)
{
fstream file;
}
c1::fun2(std::string &x,const char *y)
{
}
C file main.c:
#include "cpp.h"
void main()
{
c1 c2;
s1 structobj;
c2.fun1(&structobj);
printf("\n value of a in struct %s",structobj.a);
}

Basically, you can't.
You need to put only C functions in your header file.
You put them in a extern "C" block this way:
#ifdef __cplusplus
extern "C"
{
#endif
extern void myCppFunction(int n);
#ifdef __cplusplus
}
#endif
The extern "C" block is not recognized by a C compiler, but the C++ compiler need it to understand he have to consider functions inside as C functions.
In your cpp file you can define myCppFunction() so that she uses any C++ code, you will get a function C code can use.
Edit: I add a full example of how to link a program with a C main() using some C++ functions in a module.
stackoverflow.c:
#include "outputFromCpp.h"
int main()
{
myCppFunction(2000);
return 0;
}
outputFromCpp.h:
#ifndef OUTPUT_FROM_CPP_H
#define OUTPUT_FROM_CPP_H
#ifdef __cplusplus
extern "C"
{
#endif
extern void myCppFunction(int n);
#ifdef __cplusplus
}
#endif
#endif
outputFromCpp.cpp:
#include "outputFromCpp.h"
#include <iostream>
using namespace std;
void myCppFunction(int n)
{
cout << n << endl;
}
Compiling and linking:
gcc -Wall -Wextra -Werror -std=gnu99 -c stackoverflow.c
g++ -Wall -Wextra -Werror -std=c++98 -c outputFromCpp.cpp
g++ -o stackoverflow.exe stackoverflow.o outputFromCpp.o -static
You cannot link such a program with gcc.
If you want to link with gcc you need to put all the C++ code in a shared library, I don't put an example as it would be a bit platform dependent.

This can be done by introducing a wrapper to c++ function. The C function calls the wrapper function which inturn calls the desired C++ function (including member functions).
More details are available here

Related

Call C++ function in my C program [duplicate]

I know this.
Calling C function from C++:
If my application was in C++ and I had to call functions from a library written in C. Then I would have used
//main.cpp
extern "C" void C_library_function(int x, int y);//prototype
C_library_function(2,4);// directly using it.
This wouldn't mangle the name C_library_function and linker would find the same name in its input *.lib files and problem is solved.
Calling C++ function from C???
But here I'm extending a large application which is written in C and I need to use a library which is written in C++. Name mangling of C++ is causing trouble here. Linker is complaining about the unresolved symbols. Well I cannot use C++ compiler over my C project because thats breaking lot of other stuff. What is the way out?
By the way I'm using MSVC
You need to create a C API for exposing the functionality of your C++ code. Basically, you will need to write C++ code that is declared extern "C" and that has a pure C API (not using classes, for example) that wraps the C++ library. Then you use the pure C wrapper library that you've created.
Your C API can optionally follow an object-oriented style, even though C is not object-oriented. Ex:
// *.h file
// ...
#ifdef __cplusplus
#define EXTERNC extern "C"
#else
#define EXTERNC
#endif
typedef void* mylibrary_mytype_t;
EXTERNC mylibrary_mytype_t mylibrary_mytype_init();
EXTERNC void mylibrary_mytype_destroy(mylibrary_mytype_t mytype);
EXTERNC void mylibrary_mytype_doit(mylibrary_mytype_t self, int param);
#undef EXTERNC
// ...
// *.cpp file
mylibrary_mytype_t mylibrary_mytype_init() {
return new MyType;
}
void mylibrary_mytype_destroy(mylibrary_mytype_t untyped_ptr) {
MyType* typed_ptr = static_cast<MyType*>(untyped_ptr);
delete typed_ptr;
}
void mylibrary_mytype_doit(mylibrary_mytype_t untyped_self, int param) {
MyType* typed_self = static_cast<MyType*>(untyped_self);
typed_self->doIt(param);
}
I would do it in the following way:
(If working with MSVC, ignore the GCC compilation commands)
Suppose that I have a C++ class named AAA, defined in files aaa.h, aaa.cpp, and that the class AAA has a method named sayHi(const char *name), that I want to enable for C code.
The C++ code of class AAA - Pure C++, I don't modify it:
aaa.h
#ifndef AAA_H
#define AAA_H
class AAA {
public:
AAA();
void sayHi(const char *name);
};
#endif
aaa.cpp
#include <iostream>
#include "aaa.h"
AAA::AAA() {
}
void AAA::sayHi(const char *name) {
std::cout << "Hi " << name << std::endl;
}
Compiling this class as regularly done for C++. This code "does not know" that it is going to be used by C code. Using the command:
g++ -fpic -shared aaa.cpp -o libaaa.so
Now, also in C++, creating a C connector:
Defining it in files aaa_c_connector.h, aaa_c_connector.cpp. This connector is going to define a C function, named AAA_sayHi(cosnt char *name), that will use an instance of AAA and will call its method:
aaa_c_connector.h
#ifndef AAA_C_CONNECTOR_H
#define AAA_C_CONNECTOR_H
#ifdef __cplusplus
extern "C" {
#endif
void AAA_sayHi(const char *name);
#ifdef __cplusplus
}
#endif
#endif
aaa_c_connector.cpp
#include <cstdlib>
#include "aaa_c_connector.h"
#include "aaa.h"
#ifdef __cplusplus
extern "C" {
#endif
// Inside this "extern C" block, I can implement functions in C++, which will externally
// appear as C functions (which means that the function IDs will be their names, unlike
// the regular C++ behavior, which allows defining multiple functions with the same name
// (overloading) and hence uses function signature hashing to enforce unique IDs),
static AAA *AAA_instance = NULL;
void lazyAAA() {
if (AAA_instance == NULL) {
AAA_instance = new AAA();
}
}
void AAA_sayHi(const char *name) {
lazyAAA();
AAA_instance->sayHi(name);
}
#ifdef __cplusplus
}
#endif
Compiling it, again, using a regular C++ compilation command:
g++ -fpic -shared aaa_c_connector.cpp -L. -laaa -o libaaa_c_connector.so
Now I have a shared library (libaaa_c_connector.so), that implements the C function AAA_sayHi(const char *name). I can now create a C main file and compile it all together:
main.c
#include "aaa_c_connector.h"
int main() {
AAA_sayHi("David");
AAA_sayHi("James");
return 0;
}
Compiling it using a C compilation command:
gcc main.c -L. -laaa_c_connector -o c_aaa
I will need to set LD_LIBRARY_PATH to contain $PWD, and if I run the executable ./c_aaa, I will get the output I expect:
Hi David
Hi James
EDIT:
On some linux distributions, -laaa and -lstdc++ may also be required for the last compilation command. Thanks to #AlaaM. for the attention
Assuming the C++ API is C-compatible (no classes, templates, etc.), you can wrap it in extern "C" { ... }, just as you did when going the other way.
If you want to expose objects and other cute C++ stuff, you'll have to write a wrapper API.
You will have to write a wrapper for C in C++ if you want to do this. C++ is backwards compatible, but C is not forwards compatible.
export your C++ functions as extern "C" (aka C style symbols), or use the .def file format to define undecorated export symbols for the C++ linker when it creates the C++ library, then the C linker should have no troubles reading it
#include <iostream>
//////////////
// C++ code //
//////////////
struct A
{
int i;
int j;
A() {i=1; j=2; std::cout << "class A created\n";}
void dump() {std::cout << "class A dumped: " << i << ":" << j << std::endl;}
~A() {std::cout << "class A destroyed\n";}
};
extern "C" {
// this is the C code interface to the class A
static void *createA (void)
{
// create a handle to the A class
return (void *)(new A);
}
static void dumpA (void *thisPtr)
{
// call A->dump ()
if (thisPtr != NULL) // I'm an anal retentive programmer
{
A *classPtr = static_cast<A *>(thisPtr);
classPtr->dump ();
}
}
static void *deleteA (void *thisPtr)
{
// destroy the A class
if (thisPtr != NULL)
{
delete (static_cast<A *>(thisPtr));
}
}
}
////////////////////////////////////
// this can be compiled as C code //
////////////////////////////////////
int main (int argc, char **argv)
{
void *handle = createA();
dumpA (handle);
deleteA (handle);
return 0;
}
You can prefix the function declaration with extern “C” keyword, e.g.
extern “C” int Mycppfunction()
{
// Code goes here
return 0;
}
For more examples you can search more on Google about “extern” keyword. You need to do few more things, but it's not difficult you'll get lots of examples from Google.

Linking error when Calling a C header file

I am calling a C function from a header file I wrote in Qt written in Cpp. I keep getting a linking error when I try to compile my Qt Application.
here is the header file:
#ifndef GROUND_SERVER_H
#define GROUND_SERVER_H
#ifdef __cplusplus
extern "C" {
#endif
struct system_info{
char id[33];
};
/* Support function for the below function */
void Generate_Key(char*,char*,char*);
/* Runs the actual key generation as well as
moves the file to the respectful card or
USB drive inserted in the system that will
act as the user system key */
void run_key_generation(struct system_info*,char*,char*);
/* Function to run the server on a selected
port at which the medium that the server
is to listen on will be connected. */
void run_server(unsigned short);
void generate_id();
#ifdef __cplusplus
};
#endif
#endif
#include "foo.h" is only the textual inclusion of the contents of foo.h into the current compilation unit. If you implement a function in a different file, then you need to compile that file, too, and link the resulting object files to form an executable (or library).
This does also apply when mixing C and C++ (or most other compiled) code: You compile the source code files with the compiler suitable for the language they're written in, and finally link everything together.
So:
foo.h
#ifndef FOO_H
#define FOO_H 1
#ifdef __cplusplus
extern "C" {
#endif
int answer(void);
#ifdef __cplusplus
}
#endif
#endif
foo.c
int answer(void) {
return 42;
}
bar.cc
#include <iostream>
#include "foo.h"
int main(int argc, char ** argv) {
std::cout << "The answer is " << answer() << std::endl;
return 0;
}
To create an executable from these files, you need to:
gcc -c foo.c # Compile C file
g++ -c bar.cc # Compile C++ file
g++ -o foobar foo.o bar.o # Link

Linking C compiled static library to C++ Program

I tried to link a static library (compiled with gcc) to a c++ program and I got 'undefined reference'. I used gcc and g++ version 4.6.3 on a ubuntu 12.04 server machine. For example, here is the simple library file for factorial method:
mylib.h
#ifndef __MYLIB_H_
#define __MYLIB_H_
int factorial(int n);
#endif
mylib.c
#include "mylib.h"
int factorial(int n)
{
return ((n>=1)?(n*factorial(n-1)):1);
}
I created object for this mylib.c using gcc:
gcc -o mylib.o -c mylib.c
Again the static library was created from the object file using AR utility:
ar -cvq libfact.a mylib.o
I tested this library with a C program (test.c) and C++ program (test.cpp)
Both C and C++ program have the same body:
#include "mylib.h"
int main()
{
int fact = factorial(5);
return 0;
}
Assuming static library libfact.a is available in /home/test directory, I compiled my C program without any issues:
gcc test.c -L/home/test -lfact
However while testing C++ program, it threw a link error:
g++ test.cpp -L/home/test -lfact
test.cpp:(.text+0x2f): undefined reference to `factorial(int)'
collect2: ld returned 1 exit status
I even tried adding extern command in test.cpp:
extern int factorial(int n) //added just before the main () function
Still the same error.
Can someone tell me what I am wrong here?
Is there anything I missed while creating the static library?
Do I have to add anything in my test.cpp to make it work?
The problem is that you haven't told your C++ program that factorial is written in C. You need to change your test.h header file. Like this
#ifndef __MYLIB_H_
#define __MYLIB_H_
#ifdef __cplusplus
extern "C" {
#endif
int factorial(int n);
#ifdef __cplusplus
}
#endif
#endif
Now your header file should work for both C and C++ programs. See here for details.
BTW names containing a double underscore are reserved for the compliler (so are names starting with an underscore and a capital letter) so #ifndef __MYLIB_H_ is illegal strictly speaking. I would change to #ifndef MYLIB_H #define MYLIB_H
While the accepted answer is absolutely correct, I thought I'd just add an observation. Some editors have trouble with the open / close brace, and will indent the entire extern "C" scope in the header. If mylib.h is a key header for a library, you might consider:
#if defined (__cplusplus)
#define _MYLIB_INIT_DECL extern "C" {
#define _MYLIB_FINI_DECL }
#else
#define _MYLIB_INIT_DECL
#define _MYLIB_FINI_DECL
#endif
All other headers in mylib library, e.g., mylib_aux.h, can be of the form:
#ifndef _MYLIB_AUX_H
#define _MYLIB_AUX_H
#include <mylib.h>
_MYLIB_INIT_DECL
... header content ...
_MYLIB_FINI_DECL
#endif /* _MYLIB_AUX_H */
Obviously, the names I'm using are arbitrary, but for multiple library headers, this approach has been useful to me.

Call a C function from C++ code

I have a C function that I would like to call from C++. I couldn't use "extern "C" void foo()" kind of approach because the C function failed to be compiled using g++. But it compiles fine using gcc. Any ideas how to call the function from C++?
Compile the C code like this:
gcc -c -o somecode.o somecode.c
Then the C++ code like this:
g++ -c -o othercode.o othercode.cpp
Then link them together, with the C++ linker:
g++ -o yourprogram somecode.o othercode.o
You also have to tell the C++ compiler a C header is coming when you include the declaration for the C function. So othercode.cpp begins with:
extern "C" {
#include "somecode.h"
}
somecode.h should contain something like:
#ifndef SOMECODE_H_
#define SOMECODE_H_
void foo();
#endif
(I used gcc in this example, but the principle is the same for any compiler. Build separately as C and C++, respectively, then link it together.)
Let me gather the bits and pieces from the other answers and comments, to give you an example with cleanly separated C and C++ code:
The C Part:
foo.h:
#ifndef FOO_H
#define FOO_H
void foo(void);
#endif
foo.c
#include "foo.h"
void foo(void)
{
/* ... */
}
Compile this with gcc -c -o foo.o foo.c.
The C++ Part:
bar.cpp
extern "C" {
#include "foo.h" //a C header, so wrap it in extern "C"
}
void bar() {
foo();
}
Compile this with g++ -c -o bar.o bar.cpp
And then link it all together:
g++ -o myfoobar foo.o bar.o
Rationale:
The C code should be plain C code, no #ifdefs for "maybe someday I'll call this from another language". If some C++ programmer calls your C functions, it's their problem how to do that, not yours. And if you are the C++ programmer, then the C header might not be yours and you should not change it, so the handling of unmangled function names (i.e. the extern "C") belongs in your C++ code.
You might, of course, write yourself a convenience C++ header that does nothing except wrapping the C header into an extern "C" declaration.
I agree with Prof. Falken's answer, but after Arne Mertz's comment I want to give a complete example (the most important part is the #ifdef __cplusplus):
somecode.h
#ifndef H_SOMECODE
#define H_SOMECODE
#ifdef __cplusplus
extern "C" {
#endif
void foo(void);
#ifdef __cplusplus
}
#endif
#endif /* H_SOMECODE */
somecode.c
#include "somecode.h"
void foo(void)
{
/* ... */
}
othercode.hpp
#ifndef HPP_OTHERCODE
#define HPP_OTHERCODE
void bar();
#endif /* HPP_OTHERCODE */
othercode.cpp
#include "othercode.hpp"
#include "somecode.h"
void bar()
{
foo(); // call C function
// ...
}
Then you follow Prof. Falken's instructions to compile and link.
This works because when compiling with gcc, the macro __cplusplus is not defined, so the header somecode.h included in somecode.c is like this after preprocessing:
void foo(void);
and when compiling with g++, then __cplusplus is defined, and so the header included in othercode.cpp is now like that:
extern "C" {
void foo(void);
}
This answer is inspired by a case where Arne's rationale was correct. A vendor wrote a library which once supported both C and C++; however, the latest version only supported C. The following vestigial directives left in the code were misleading:
#ifdef __cplusplus
extern "C" {
#endif
This cost me several hours trying to compile in C++. Simply calling C from C++ was much easier.
The ifdef __cplusplus convention is in violation of the single responsibility principle. A code using this convention is trying to do two things at once:
(1) execute a function in C
-- and --
(2) execute the same function in C++
It's like trying to write in both American and British English at the same time. This is unnecessarily throwing an #ifdef __thequeensenglish spanner #elif __yankeeenglish wrench #else a useless tool which makes the code harder to read #endif into the code.
For simple code and small libraries the ifdef __cplusplus convention may work; however, for complex libraries it is best to pick one language or the other and stick with it. Supporting one of the languages will take less maintenance than trying to support both.
This is a record of the modifications I made to Arne's code to get it to compile on Ubuntu Linux.
foo.h:
#ifndef FOO_H
#define FOO_H
void foo(void);
#endif
foo.c
#include "foo.h"
#include <stdio.h>
void foo(void)
{
// modified to verify the code was called
printf("This Hello World was called in C++ and written in C\n");
}
bar.cpp
extern "C" {
#include "foo.h" //a C header, so wrap it in extern "C"
}
int main() {
foo();
return(0);
}
Makefile
# -*- MakeFile -*-
# dont forget to use tabs, not spaces for indents
# to use simple copy this file in the same directory and type 'make'
myfoobar: bar.o foo.o
g++ -o myfoobar foo.o bar.o
bar.o: bar.cpp
g++ -c -o bar.o bar.cpp
foo.o: foo.c
gcc -c -o foo.o foo.c

C and C++ linkage with extern "C"

I have a C++ function defined in a .h file as follows and implemented in a .cpp file:
extern "C" void func(bool first, float min, float* state[6], float* err[6][6])
{
//uses vectors and classes and other C++ constructs
}
How can I call func in a C file? How do I set up my file architecture / makefile to compile this?
Thanks!
You call the function from C in the normal way. However, you need to wrap the extern "C" in an preprocessor macro to prevent the C compiler from seeing it:
#ifndef __cplusplus
extern "C"
#endif
void func(bool first, float min, float* state[6], float* err[6][6]);
Assuming you're working with GCC, then compile the C code with gcc, compile the C++ code with g++, and then link with g++.
To call it in C, all you need to do is call it normally. Because you told the compiler to use the C calling conventions and ABI with extern "C", you can call it normally:
func(args);
To compiler, use this for the C++:
g++ -c -o myfunc.o myfunc.cpp
Then this for the C:
gcc -c -o main.o somec.c
Than link:
g++ -o main main.o myfunc.o
Make sure that the C++ header for the function uses ONLY C CONSTRUCTS. So include things like <vector> in the .cpp file instead.
call it in C using
func(/* put arguments here */);
By saying extern "C" you are asking the compiler not to mangle your names. Otherwise, C++ compiler would tend to mangle them (i.e. add additional symbols to make them unique) before the linker.
You'll also want to make sure you have setup to use C calling convention.
//header file included from both C and C++ files
#ifndef __cplusplus
#include <stdbool.h> // for C99 type bool
#endif
#ifdef __cplusplus
extern "C" {
#endif
void func(bool first, float min, float* state[6], float* err[6][6]);
#ifdef __cplusplus
} // extern "C"
#endif
// cpp file
#include "the_above_header.h"
#include <vector>
extern "C" void func(bool first, float min, float* state[6], float* err[6][6]);
{
//uses vectors and classes and other C++ constructs
}
// c file
#include "the_above_header.h"
int main() {
bool b;
float f;
float *s[6];
float *err[6][6];
func(b,f,s,err);
}