`undefined reference` when trying to interface C to call C++ - 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

Related

What is the correct way to compile multiple test sources with Catch2?

I have the following project structure:
test_main.cc
#define CATCH_CONFIG_MAIN
#include "catch2.hpp"
test1.cc
#include "catch2.hpp"
#include "test_utils.hpp"
TEST_CASE("test1", "[test1]") {
REQUIRE(1 == 1);
}
test2.cc
#include "catch2.hpp"
#include "test_utils.hpp"
TEST_CASE("test2", "[test2]") {
REQUIRE(2 == 2);
}
test_utils.hpp
#pragma once
#include <iostream>
void something_great() {
std::cout << ":)\n";
}
If I compile using something like clang++ -std=c++17 test_main.cc test1.cc test2.cc, the function something_great is defined in both test1.o and test2.o. This leads to an error like
duplicate symbol __Z15something_greatv in:
test1.cc.o
test2.cc.o
ld: 1 duplicate symbol for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
In the Scaling Up section of the Catch2 documentation, they mention that in order to split up your tests you may want to
Use as many additional cpp files (or whatever you call your
implementation files) as you need for your tests, partitioned however
makes most sense for your way of working. Each additional file need
only #include "catch.hpp"
but in the examples section of the documentation I don't see a use case like mine. I read this blog post which describes three solutions which don't appeal to me: defining functions as macros, or making functions static or inline.
Is there another way to compile these files which yield a single executable with the main function defined by test_main.cc?
This actually has nothing to do with Catch or testing. When you #include a file in C++, it gets copy-pasted at the #include line verbatim. If you put free function definitions in headers, you would see this problem building your actual program, etc.
The underlying problem is that #include is not the same kind of import-a-module directive as is the equivalent directive (import, require, etc.) in most languages, which do the sane thing in a situation like this (confirm that the header is the same one we've already seen and ignore the repeated method definition).
The commenter that suggested you write inline is technically correct, in the sense that this will "solve your problem" because your compiler won't generate object code for the method multiple times. However, it doesn't really explain what's going on or address the underlying issue.
The clean solution is:
In test_utils.hpp, replace the method definition with a method declaration: void something_great();.
Create test_utils.cc with the definition of the method (which you currently have in the .hpp).
clang++ -std=c++17 test1.cc -c
clang++ -std=c++17 test2.cc -c
clang++ -std=c++17 test_main.cc -c
clang++ -std=c++17 test_utils.cc -c
clang++ -std=c++17 test1.o test2.o test_utils.o test_main.o
I also recommend you read this: What is the difference between a definition and a declaration?
Explicitly:
// test_utils.hpp
#pragma once
// This tells the compiler that when the final executable is linked,
// there will be a method named something_great which takes no arguments
// and returns void defined; the definition lives in test_utils.o in our
// case, although in practice the definition could live in any .o file
// in the final linking clang++ call.
void something_great();
And:
// test_utils.cpp
#include "test_utils.hpp"
#include <iostream>
// Generates a DEFINITION for something_great, which
// will get put in test_utils.o.
void something_great() { std::cout << "Hi\n"; }
It seems you are worried about "recompiling Catch" every time you make a change to a test. I hate to break it to you, but you are in C++ land now: you are going to be recompiling stuff pointlessly a lot. Header-only libraries like Catch MUST be "recompiled" to some extent when a source file including them changes, because for better or worse, if the source file or a header file included transitively from the source file includes catch2.hpp, then the source code of catch2.hpp will get parsed by the compiler when that source file is read.
After some experimentation, I found a reasonable solution which doesn't require you to fully recompile Catch any time you make a change to a test.
Define test_main.cc in the same way as before:
#define CATCH_CONFIG_MAIN
#include "catch2.hpp"
Add another .cc file, test_root which includes your test files as headers:
#include "test1.hpp"
#include "test2.hpp"
Change your test sources to headers:
test1.hpp
#pragma once
#include "catch2.hpp"
#include "test_utils.hpp"
TEST_CASE("test1", "[test1]") {
REQUIRE(1 == 1);
}
test2.hpp
#pragma once
#include "catch2.hpp"
#include "test_utils.hpp"
TEST_CASE("test2", "[test2]") {
REQUIRE(2 == 2);
}
Compile separately
clang++ -std=c++17 test_main.cc -c
clang++ -std=c++17 test_root.cc -c
clang++ test_main.o test_root.o
Where test_main.cc needs only be compiled once. test_root.cc will need to be recompiled whenever you change your tests and of course you must relink the two object files.
I will leave this answer unaccepted for now in case there are better solutions.

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.

Linking C++ static Library in C using gcc

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.

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.