Article Directory
In the project development process, our underlying code is often
C
used for implementation, and most of the upper-level applications areC++
implemented, so we are involved in the situation of callingC
andC++
calling each other. So,C/C++
how to achieve mutual calls?
1. Why is there a difference?
- Compilation methods are different :
C
files are oftengcc
compiledCpp
usingg++
C++
Support function overloading : Due to this feature, the same function inC++
andC
in will generate different function names after compilation.
This has led to the C
inability C++
to directly call between and, to solve this problem, you have to rely on extern "C"
help.
2、extern “C”
- extern
extern
We are not unfamiliar with keywords. It is an attribute in programming languages, which is used to indicate the scope of variables, functions and other types.
We often
.c
define variables or implement functions in source files,.h
and useextern
keywords to declare them in header files, which is convenient for other files to call.
- “C”
There are many kinds of programming languages, and different languages have different compilation rules. If you want to call each other, you must tell the compiler what rules to compile the file, so that it can be called normally.
Its main function is : use it “C”
as a flag to tell the compiler that the following code C
is compiled in the way!
After understanding the principle, let's practice it!
3. C++ calls C
We create 3 files, respectively main.cpp
, cal.c
, cal.h
.
We use gcc
and g++
compile files separately, and compile cal.o
two main.o
intermediate files. It is very simple and defines a embedded_art
function.
# dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test on git:main x [15:57:32]
$ ls
cal.c cal.h main.cpp
# dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test on git:main x [15:57:43]
$ gcc -c cal.c
# dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test on git:main x [15:57:49]
$ g++ -c main.cpp
# dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test on git:main x [15:57:55]
$ ls
cal.c cal.h cal.o main.cpp main.o
Let's take a look at the compiled intermediate file cal.o
and the symbol table to see the difference between different compilation methods for the main.o
same function .embedded_art
It can be seen that g++
after compilation, the function name is processed, and a new function name is finally generated according to its own compilation rules, so if we directly call cal.c
it, it will embedded_art
definitely not work.
correct way
Use extern "C"
to make the g++
compiler compile C
in the same way.
In the main.cpp
file, where we import cal.h
, addextern "C"
extern "C" {
#include "cal.h"
}
Compile again and you're done!
You can see that in the symbol table, the function name is normal, and then we link the intermediate file, execute it, and output the correct result!
# dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test on git:main x [16:18:36]
$ g++ main.o cal.o
# dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test on git:main x [16:19:54]
$ ls
a.out cal.c cal.h cal.o main.cpp main.o
# dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test on git:main x [16:19:57]
$ ./a.out
main entry
嵌入式艺术
4. C calls C++
We create 3 files, respectively main.c
, cal.cpp
, cal.h
.
We use gcc
and g++
compile files separately, and compile cal.o
two main.o
intermediate files, which is very simple and also defines a embedded_art
function.
# dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test/c_call_c++ on git:main x [16:24:45]
$ g++ -c cal.cpp
# dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test/c_call_c++ on git:main x [16:24:52]
$ gcc -c main.c
# dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test/c_call_c++ on git:main x [16:24:56]
$ ls
cal.cpp cal.h cal.o main.c main.o
Let's take a look at the compiled intermediate file cal.o
and the symbol table to see the difference between different compilation methods for the main.o
same function .embedded_art
Also, different compilers handle it differently, and the function names are still different! Also, need to be added extern "C"
to tell the compiler to C
compile by .
We cal.h
add in the declaration section, and then recompile!
extern "C" {
extern void embedded_art(void);
}
You can see that in the symbol table, the function name is normal, and then we link the intermediate files.
At this time, an error will be reported
extern "C"
. What is the situation?
In the main.c
file, c++
the header file is introduced cal.h
, because it can only be recognized "C"
at compile time , and there is no such keyword in the language.C++
C
Therefore, we need g++
to add extern "C"
it when compiling, and gcc
skip it during compiling. At this time, we need to mention c++
the specific macros __cplusplus
during compiling, which is equivalent to a valve.
We modify the cal.h
file :
#ifdef __cplusplus
extern "C" {
#endif
extern void embedded_art(void);
#ifdef __cplusplus
}
#endif
In this way, it is ensured that when the function is compiled, the c++
syntax is used to compile, and when it is compiled, it is not processed.embedded_art
C
gcc
Link again, execute!
# dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test/c_call_c++ on git:main x [16:45:06] C:1
$ gcc -no-pie cal.o main.o -o main
# dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test/c_call_c++ on git:main x [16:46:46]
$ ls
cal.cpp cal.h cal.o main main.c main.o
# dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test/c_call_c++ on git:main x [16:49:01]
$ ./main
main entry
嵌入式艺术
5. Summary
C/C++
In the final analysis, the mutual calls between them are: different languages have different compilation rules. If you want to achieve universal use, you must tell the compiler to compile according to the rules of the target language!
Like + follow, never get lost