π Follow our official account and select Star, to receive the latest content daily
Introduction
This article demonstrates the core technologies of C/C++ mixed programming through practical projects. It covers essential knowledge points from the basic extern "C" linkage specification to the complete compilation process, including name mangling, header file design, and CMake build. By combining practical cases in the Windows MSVC environment, it helps readers master the essence of collaboration between the two languages and solve compatibility issues in real projects.

Basic Concepts
What is C/C++ Mixed Programming?
Writing code in both C and C++ languages within the same project, allowing them to call each other.
Why is Mixed Programming Needed?
- Legacy Code: Utilizing existing C language libraries
- Performance Considerations: C language performs better in certain scenarios
- Library Compatibility: Many low-level libraries are written in C
- Team Skills: Team members have varying familiarity with different languages
Core Technical Points
1. Name Mangling Issues
Cause of the Problem:
- C Compiler: Function name
<span>add</span>β Symbol name<span>add</span> - C++ Compiler: Function name
<span>add</span>β Symbol name<span>?add@@YAHHH@Z</span>(supports function overloading)
Solution: Use <span>extern "C"</span> to inform the C++ compiler to use C linkage conventions.
2. Usage of extern “C”
// Method 1: Single function
extern "C" int c_function(int a, int b);
// Method 2: Multiple functions
extern "C" {
int func1(int a);
int func2(int b);
}
// Method 3: Conditional compilation (recommended)
#ifdef __cplusplus
extern "C" {
#endif
int c_function(int a, int b);
#ifdef __cplusplus
}
#endif
3. Header File Design Patterns
Standard Mixed Programming Header File Template:
#ifndef HEADER_NAME_H
#define HEADER_NAME_H
#ifdef __cplusplus
extern "C" {
#endif
// C function declarations
int c_function(int a, int b);
void c_procedure(const char* str);
#ifdef __cplusplus
}
#endif
// C++ specific section
#ifdef __cplusplus
class CppClass {
public:
int cpp_method(int a, int b);
};
int cpp_function(int a, int b);
#endif
#endif // HEADER_NAME_H
4. Compiler Selection Mechanism
CMake Automatic Selection:
<span>.c</span>files β C compiler<span>.cpp</span>,<span>.cxx</span>,<span>.cc</span>files β C++ compiler
Compilation Parameter Confirmation:
- Windows MSVC:
<span>/TC</span>(C mode),<span>/TP</span>(C++ mode) - Linux GCC:
<span>gcc</span>(C compiler),<span>g++</span>(C++ compiler)
Practical Examples
Project Structure
project/
βββ CMakeLists.txt
βββ main.cpp (C++ main program)
βββ math_c.c (C implementation)
βββ math_cpp.cpp (C++ implementation)
βββ math_functions.h (mixed header file)
1. CMakeLists.txt
cmake_minimum_required(VERSION 3.10.0)
project(
mixed_programming
VERSION 1.0.0
LANGUAGES C CXX)
# Add executable file
add_executable(${PROJECT_NAME}
main.cpp
math_c.c
math_cpp.cpp
)
# Optional: Set C++ standard
set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 17)
2. Header File (math_functions.h)
#ifndef MATH_FUNCTIONS_H
#define MATH_FUNCTIONS_H
#ifdef __cplusplus
extern "C" {
#endif
// C function declarations
int add_c(int a, int b);
int multiply_c(int a, int b);
void print_result_c(const char* operation, int result);
#ifdef __cplusplus
}
#endif
// C++ function declarations
#ifdef __cplusplus
#include <string>
int add_cpp(int a, int b);
int multiply_cpp(int a, int b);
void print_result_cpp(const std::string& operation, int result);
// C++ class
class Calculator {
private:
std::string name;
public:
Calculator(const std::string& calc_name);
int calculate(int a, int b, char op);
void show_history() const;
};
#endif
#endif // MATH_FUNCTIONS_H
3. C Language Implementation (math_c.c)
#include <stdio.h>
#include "math_functions.h"
int add_c(int a, int b) {
printf("[C Function] Calculation: %d + %d\n", a, b);
return a + b;
}
int multiply_c(int a, int b) {
printf("[C Function] Calculation: %d * %d\n", a, b);
return a * b;
}
void print_result_c(const char* operation, int result) {
printf("[C Function] The result of %s is: %d\n", operation, result);
}
4. C++ Language Implementation (math_cpp.cpp)
#include <iostream>
#include <vector>
#include "math_functions.h"
// C++ function implementation
int add_cpp(int a, int b) {
std::cout << "[C++ Function] Calculation: " << a << " + " << b << std::endl;
return a + b;
}
int multiply_cpp(int a, int b) {
std::cout << "[C++ Function] Calculation: " << a << " * " << b << std::endl;
return a * b;
}
void print_result_cpp(const std::string& operation, int result) {
std::cout << "[C++ Function] " << operation << " The result is: " << result << std::endl;
}
// C++ class implementation
Calculator::Calculator(const std::string& calc_name) : name(calc_name) {
std::cout << "Creating calculator: " << name << std::endl;
}
int Calculator::calculate(int a, int b, char op) {
switch(op) {
case '+': return add_cpp(a, b);
case '*': return multiply_cpp(a, b);
default: return 0;
}
}
void Calculator::show_history() const {
std::cout << "Calculator " << name << " history" << std::endl;
}
5. Main Program (main.cpp)
#include <iostream>
#include "math_functions.h"
int main() {
std::cout << "=== C/C++ Mixed Programming Example ===" << std::endl;
// Call C functions
std::cout << "\n--- Calling C Functions ---" << std::endl;
int result_c1 = add_c(10, 20);
int result_c2 = multiply_c(5, 6);
print_result_c("Addition", result_c1);
print_result_c("Multiplication", result_c2);
// Call C++ functions
std::cout << "\n--- Calling C++ Functions ---" << std::endl;
int result_cpp1 = add_cpp(15, 25);
int result_cpp2 = multiply_cpp(7, 8);
print_result_cpp("Addition", result_cpp1);
print_result_cpp("Multiplication", result_cpp2);
// Use C++ class
std::cout << "\n--- Using C++ Class ---" << std::endl;
Calculator calc("Mixed Calculator");
int result_class = calc.calculate(12, 8, '+');
calc.show_history();
// Demonstrate mutual calls
std::cout << "\n--- Mixed Calls ---" << std::endl;
std::cout << "C++ calls C function result: " << add_c(100, 200) << std::endl;
return 0;
}
Compilation and Linking Process
Complete Compilation Process
1. Configuration Stage (cmake)
βββ Read CMakeLists.txt
βββ Detect C/C++ compilers
βββ Generate build files (.vcxproj/.sln or Makefile)
βββ Save configuration to CMakeCache.txt
2. Build Stage (cmake --build)
βββ Preprocessing (Preprocessing)
β βββ main.cpp + headers β main.i
β βββ math_c.c + headers β math_c.i
β βββ math_cpp.cpp + headers β math_cpp.i
β (Note: After preprocessing, header files disappear, content merges into .i files)
β
βββ Compilation (Compilation)
β βββ main.i β main.s (assembly code)
β βββ math_c.i β math_c.s (assembly code)
β βββ math_cpp.i β math_cpp.s (assembly code)
β
βββ Assembly (Assembly)
β βββ main.s β main.obj (machine code)
β βββ math_c.s β math_c.obj (machine code)
β βββ math_cpp.s β math_cpp.obj (machine code)
β
βββ Linking (Linking)
βββ Symbol resolution: matching function calls and definitions
βββ Address relocation: determining final memory addresses
βββ Library linking: linking system libraries and runtime libraries
βββ Generate executable file: mixed_programming.exe
Key Compilation Parameters
Windows (MSVC):
# C++ file compilation
cl.exe /c /TP main.cpp math_cpp.cpp
# C file compilation
cl.exe /c /TC math_c.c
# Linking
link.exe main.obj math_c.obj math_cpp.obj /OUT:program.exe
Linux (GCC):
# C++ file compilation
g++ -c main.cpp math_cpp.cpp
# C file compilation
gcc -c math_c.c
# Linking
g++ main.o math_c.o math_cpp.o -o program
Common Issues and Solutions
1. Linking Error: unresolved external symbol
Error Phenomenon:
error LNK2019: unresolved external symbol "int __cdecl add_c(int,int)"
Cause: Missing <span>extern "C"</span> declaration
Solution:
// Add in header file
extern "C" int add_c(int a, int b);
2. Redefinition Error
Error Phenomenon:
error LNK2005: add_c already defined
Cause: Function definitions included in the header file
Solution:
- Only declarations in header files, no definitions
- Use
<span>inline</span>keyword (only for simple functions) - Add header file protection
3. C++ Features Error in C Code
Error Phenomenon:
// In .c file
std::cout << "Hello"; // Error! C does not support C++ syntax
Solution:
- Use only C syntax in C files
- C++ features only in .cpp files
4. Header File Duplicate Inclusion
Solution: Use header file protection
#ifndef HEADER_NAME_H
#define HEADER_NAME_H
// Header file content
#endif
Best Practices
1. Project Organization
project/
βββ include/ # Public header files
β βββ api.h
βββ src/
β βββ c_module/ # C language module
β β βββ module.c
β β βββ module.h
β βββ cpp_module/ # C++ language module
β β βββ module.cpp
β β βββ module.hpp
β βββ main.cpp
βββ CMakeLists.txt
βββ README.md
2. Naming Conventions
// C functions: use underscore naming
int calculate_sum_c(int a, int b);
// C++ functions: use camel case naming
int calculateSumCpp(int a, int b);
// File naming
module.c // C implementation
module.cpp // C++ implementation
module.h // C/C++ compatible header file
module.hpp // Pure C++ header file
3. Error Handling
// C style error handling
extern "C" {
typedef enum {
SUCCESS = 0,
ERROR_INVALID_PARAM = -1,
ERROR_MEMORY = -2
} ErrorCode;
ErrorCode process_data_c(const char* data, int* result);
}
// C++ style error handling
#ifdef __cplusplus
#include <stdexcept>
class ProcessingException : public std::exception {
public:
const char* what() const noexcept override {
return "Processing failed";
}
};
void processDataCpp(const std::string& data);
#endif
4. Memory Management
// C style memory management
extern "C" {
char* allocate_buffer_c(size_t size);
void free_buffer_c(char* buffer);
}
// C++ style memory management
#ifdef __cplusplus
#include <memory>
std::unique_ptr<char[]> allocateBufferCpp(size_t size);
#endif
5. Build Script Optimization
# Set compilation options
if(MSVC)
# Windows specific settings
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W4")
else()
# Linux/Unix specific settings
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra")
endif()
# Handle C and C++ files separately
set_source_files_properties(
${C_SOURCES}
PROPERTIES LANGUAGE C
)
set_source_files_properties(
${CXX_SOURCES}
PROPERTIES LANGUAGE CXX
)
Conclusion
The key to C/C++ mixed programming lies in:
- Understanding Compiler Differences: C and C++ have different compilation and linking rules
- **Correctly Using extern “C”**: Resolving name mangling issues
- Well-Designed Header Files: Using conditional compilation to support both languages
- Following Best Practices: Project organization, naming conventions, error handling
By mastering these knowledge points, you can successfully implement C/C++ mixed programming in your projects, fully leveraging the advantages of both languages.
βTHE ENDβ
For the latest updates and experiences with large model agents, please follow our mini-programππ

Reply “Join Group” in the official account to join the mutual assistance group, and you can get the complete keyword list in the γmenuγ of the official account (updated irregularly).

This article is for academic sharing only. If there is any infringement, please contact us for deletion. Thank you very much!