Linking C++ static Library in C using gcc - c++

In the following code, I am trying to call a dummy function written in C++ (using C++ header files like ap_fixed.h, ap_int.h) from a C function. The code runs fine when I compile with g++. But when I use gcc for compiling test.c, it throws an error because I have included a C++ header file which is a valid error.
Is there any workaround to compile using gcc? I have read from some posts that it is not a good practice to merge C/C++ code in this manner. Please enlighten me if there are any serious repurcussions of working with a large C codebase and doing similar stuff.
Thanks
Header File: testcplusplus.h
#include "ap_fixed.h"
#include "ap_int.h"
#ifdef __cplusplus
extern "C" {
#endif
void print_cplusplus();
#ifdef __cplusplus
}
#endif
testcplusplus.cc
#include <iostream>
#include "testcplusplus.h"
void print_cplusplus() {
ap_ufixed<10, 5,AP_RND_INF,AP_SAT > Var1 = 22.96875;
std::cout << Var1 << std::endl;
}
test.c
#include <stdio.h>
#include "testcplusplus.h"
int main() {
print_cplusplus();
}
Commands Used:
g++ -c -o testcplusplus.o testcplusplus.cc
ar rvs libtest.a testcplusplus.o
gcc -o test test.c -L. -ltest
Error:
In file included from ap_fixed.h:21:0,
from testcplusplus.h:1,
from test.c:2:
ap_int.h:21:2: error: #error C++ is required to include this header file

The problem here is that the C++ header ap_fixed.h is included from the C program test.c (indirectly via testcplusplus.h).
The solution is to remove the include of headers "ap_fixed.h"
and "ap_int.h" from testcplusplus.h and include them directly from testcplusplus.cpp. The C program doesn't need to know about these anyway, only the C++ wrapper uses them directly.
In a larger example it might be appropriate to split testcplusplus.h into two headers: one that contains only declarations of the external interface you are presenting to the C environment, and another containing the rest - declarations needed internally in the C++ implementation and any required includes.
Once you have done this, you will still face linking errors because the executable that is produced will contain references to symbols from the C++ runtime libraries, plus any other libraries that your C++ code uses. To solve this, add -l directives when compiling the final executable, eg:
gcc -o test test.c -L. -ltest -lstdc++

You do not need to include ap_int.h and ap_fixed.h at this point, as the declaration of the print_cplusplus function does not need those definitions.
Rather, include them in testcplusplus.c, so the C compiler can only see the C compatible interface of the C++ code.

Related

C wrapper around C++ library without unnecessary header files

C++ newbie here. I'm creating a C wrapper around C++ library which expose just foo() function.
wrapper.h
#include "SomeLibrary.h"
#include "SomeAnotherLibrary.h"
#ifdef __cplusplus
extern "C" {
#endif
void foo();
#ifdef __cplusplus
}
#endif
wrapper.cpp
#include "wrapper.h"
void foo() {
// calls to `SomeLibrary.h` and `SomeAnotherLibrary.h` functions...
}
I would like to compile this code just to be able to call foo() from a different C code. Note that I care just about the foo() function. I would like to completely ignore SomeLibrary.h and SomeAnotherLibrary.h header files.
So I tried to compilethe wrapper into object file wrapper.o as follows:
g++ -c wrapper.cpp -o wrapper.o -I../some_library/include -I../some_other_library/include -L../some_library/lib -lSomeFirstLibrary -lSomeSecondLibrary
Problem:
When I used wrapper.o in my C project, it still require me to load bunch of header files from SomeLibrary.h and SomeAnotherLibrary.h (which I do not care about at all). Here is my C project code:
my_project.c:
#include "wrapper.h"
void main() {
foo();
}
And compile it:
gcc my_project.c wrapper.o -o my_project
Which yields following error:
my_program.c:3:28: fatal error: SomeLibrary.h: No such file or directory
Question:
How I should compile the wrapper to ignore all other header files except wrapper.h?
Remove
#include "SomeLibrary.h"
#include "SomeAnotherLibrary.h"
from wrapper.h and put those lines in wrapper.cpp next to #include "wrapper.h".
Then remove the -L../some_library/lib -lSomeFirstLibrary -lSomeSecondLibrary linker related flags from the
g++ -c wrapper.cpp -o wrapper.o -I../some_library/include -I../some_other_library/include
command (-c means no linking is done here so there's no point in passing linker flags)
and move it to the
gcc my_project.c wrapper.o -o my_project -L../some_library/lib -lSomeFirstLibrary -lSomeSecondLibrary
command like this.
Then it should work.
When you get undefined reference to... messages, it means that you are declaring functions, and calling them, but never defining them. The error is coming from the fact that you are linking your libraries in the wrong place. You do not need to link libraries to the .o file, you need to link them to the executable file.

`undefined reference` when trying to interface C to call C++

I was trying to call C++ from C. I am not sure about the linking order. It could have been that to cause the error. For some reasons, the compiler complains undefined reference to helloWorld.
Could anyone advise?
main.c:
#include "example.h"
#include <stdio.h>
int main(){
helloWorld();
return 0;
}
example.h:
#ifndef HEADER_FILE
#define HEADER_FILE
#ifdef __cplusplus
extern "C" {
#endif
void helloWorld();
#ifdef __cplusplus
}
#endif
#endif
example.cpp:
#include "example.h"
#include <iostream>
void helloWorld(){
std::cout << "Hello World from CPP";
}
There are two ways to do this. While both work, one is "cleaner" than the other. Side note: As trojanfoe pointed out, you may have left off the .o on the compile/link command.
Here's a two step process:
cc -c main.c
c++ -o mypgm example.cpp main.o
This is a bit ugly because the usual convention is that the source that gets compiled is the one with main
Here's the more usual way:
c++ -c example.cpp
cc -c main.c
c++ -o mypgm main.o example.o
NOTE: In both cases, the "linker" must be c++ to resolve the std::* that example.cpp uses
UPDATE:
What is mypgm?
mypgm [just an example name] is the name of the [fully linked and ready to run] output executable or program. It's the argument for the -o option. The linker takes your relocatable input .o files, links them together to produce the output file [that can now be run as a command].
It's pretty standard nomenclature for something that is arbitrary in example instruction or code sequences [like here on SO]. You could replace "mypgm" with "ursa_majors_test_program" or "example", or whatever you'd like. To run the program, then type ./mypgm [or ./ursa_majors_test_program or ./example]
There's no magic to the name, just like there was no magic to you naming your source files main.c and example.cpp
It should be descriptive of function. If you had said you were working on a text editing program, in my example, I might have used -o editor

How do I compile "c++ functions from c" if c++ functions need other libraries?

I have these files in the same folder:
function.h
function.cpp
main.c
If I have a simple function like sum(int a){return a+a;} (in function.cpp), I am able to compile it, but I need to use a library like this:
#include "something.hh"
void function(){
ClassX* test;
...
}
The problem is that, when I'm trying to compile this, I get "undefined reference" in every class.
How should I compile this?
Is this possible? I've read somewhere you can use a c++ function in c while its return type and its parameters are accessible from C. Is there any other requirement?
What I do:
g++ -c -I /folder/include function.cpp -o function.o
gcc -c main.c -o main.o
gcc main.o function.o -o exec
In function.cpp undefined reference to ClassX
I think your problem is not use of C and C++ but that file containing entire ClassX is not compiled and hence in the third stage in link time it gives error
gcc main.o function.o -o exec
Make sure that ClassX is defined in one .o file and that file is passed in above step.
Now coming to your question,
you can't compile C++ code is C compilers because C is not forward compatible but C++ is backward compatible to C that is to say that most of the C code will get compiled by C++ compiler with little change. But you can write a library in c or compile c code to .o and then use it in C++ compiler to do that you need to use extern "C" linkage.
extern "C"
{
....
}
Check this link
Thanks
How should i compile this? Is this possible?
Normally, there are two possibilities:
define your header file API in terms of functions only, declare those functions with extern "C" linkage and use them in C code.
if you have class declarations or other C++ specific code, compile your client code to C++ (i.e. move main.c to main.cpp).
In your case, you are trying to access a C++ class, in C code. This is not possible.
You can still use the functionality, but you will have to create an adaptation layer (with APIs declared as extern "C" and declaring no classes, templates or other C++ features).
Within this adaptation layer, classes or other C++ constructs can be hidden in structures opaque to client code.

Confusion between including header files and source files in main program

I have heard that we should write the declarations in a header file and the definition in a source file, with both the source and the header having the same name. And then just include the header in the source.
Here is an example myFile.h:
void printer (void);
Here is the implementation of printer in myFile.cpp:
#include "myFile.h"
#include <iostream>
using namespace std;
void printer ()
{
cout<< "I am a printer";
}
Here is my main.cpp:
#include "myFile.h"
int main ()
{
printer();
return 0;
}
Now when I run the program, I get the expected error: undefined reference to printer. But when I see code on github or other projects I see that usually they have included the header file and not the source file. I also tried using the header guards ifndef but still the same error came.
The main program is successfully compiled if:
If i include myFIle.cpp in myFile.h
If i include just myFile.cpp in main
What I the general practice while doing the same?
You should include your myFile.cpp in the linking process:
g++ myFile.cpp main.cpp
The error message undefined reference to printer is actual a linker error, not a compiler error.
Explanation
If you use only g++ main.cpp compiler won't create code from myFile.cpp. He knows that there should be a function with the signature void printer(void), but he doesn't now yet where this function is. He completely ignores this fact, since you can provide pre-compiled object files ("myFile.o") and link those later:
g++ myFile.cpp -c # compile myFile.cpp
g++ main.cpp -c # compile myFile.cpp
g++ myFile.o main.o # link both files together.
-c will tell g++ only to compile the files, but not link them together to an executable. This is done by a linker (g++ will probably call ld in your configuration). The linker will create an executable which contains all needed libraries like libc++ and actual code.
IDE remarks
If you use an IDE make sure that all needed files are included in the project. This includes all header and source files and linkage options for additional libraries.
When yourself define a header file and want to include it, you should enclose it "", such as :
#include "myFile.h"
#include "myFile.h" // would be better.
It seems you forgot the " surrounding the include.
You should use
#include "myFile.h"
or
#include <myFile.h>
the later is rather for system libraries. Both forms differ in the way the search the file.
You find more details on
http://msdn.microsoft.com/en-us/library/36k2cdd4%28v=vs.71%29.aspx

Trying to compile cross-platform C++ code.Undefined reference to C function

I used the C-library RS232 in my C++ code to control an Arduino Uno board. In my main.cpp, I got:
#include "rs232.h"
because in the rs232.h header file, they already have:
#ifdef __cplusplus
extern "C" {
#endif
In one folder, I have:
main.cpp
rs232.h
rs232.c
stdafx.h
stdafx.cpp
and I use cygwin to compile so that the code could be used for Linux:
g++ main.cpp
but I got errors with "...undefined reference to '_OpenComport'" and similar to all C functions that I called from my main.cpp.
Can anyone tell me how to include the C header file in C++? Or is it that I used the wrong command for g++?
You need to pass all source files to the compiler, like so
g++ -o demo.exe main.cpp rs232.c stdafx.cpp
Alternatively, compile parts into a library, and separate compile and link steps.