C++是C的超集。C++兼容绝大部分C语言的语法。C、C++天然可以混合编译。需要注意的一点就是C、C++在编译过程中,对于函数名的处理,C语言使用简单参数名,不考虑参数个数、参数类型,而C++函数将参数类型列表当作函数名的一部分。通过使用特殊关键字使得C++可以声明、调用C函数,以下举例:
1)C++程序调用C程序
a.h
#ifndef A_H
#define A_H
void f(int i);
int g(int n);
#endif // A_H
a.c
#include <stdio.h>
void f(int i) {
printf("int: %d\n", i);
}
int g(int n) {
n = n + 1;
return n;
}
b.h
#ifndef B_H
#define B_H
void displayB(int, int);
#endif // B_H
b.cpp
#include <iostream>
extern "C" {
#include "a.h"
}
void displayB(int i, int n) {
f(i);
int result = g(n);
std::cout << result << std::endl;
}
main.cpp
#include "b.h"
int main() {
displayB(1, 3);
return 0;
}
执行命令
gcc -o a.c
g++ a.o b.cpp main.cpp -o main
./main
结果:
int: 1
4
备注:如果在b.cpp中不加入extern "C",则在编译时会报如下错误,报错的原因以上已说明
/tmp/ccf26t2V.o: In function `displayB(int, int)':
b.cpp:(.text+0x14): undefined reference to `f(int)'
b.cpp:(.text+0x1e): undefined reference to `g(int)'
collect2: error: ld returned 1 exit status
2)C调用C++程序(C++程序不涉及类、成员函数)
a.h
#ifndef A_H
#define A_H
extern "C" {
void displayA(int a);
}
#endif
a.cpp
#include <stdio.h>
#include "a.h"
void displayA(int a) {
printf("%d\n", a);
}
b.h
#ifndef B_H
#define B_H
void displayA(int b);
void displayB(int b);
#endif
b.c
#include <stdio.h>
#include "b.h"
void displayB(int b) {
printf("%d\n", b);
displayA(b-1);
}
main.c
#include "b.h"
int main() {
displayB(2);
return 0;
}
执行命令
g++ -o a.cpp
gcc a.o b.c main.c -o main
./main
执行结果:
2
1
备注:如果在a.h中不加入extern "C",则在编译时会报如下错误,报错的原因以上已说明
/tmp/ccnXvgt4.o: In function `displayB':
b.c:(.text+0x28): undefined reference to `displayA'
collect2: error: ld returned 1 exit status
3)C调用C++程序(C++程序涉及类、成员函数),使用C、C++通用的结构体struct对C++中的类class进行包装
Animal.h
#ifndef ANIMAL_H
#define ANIMAL_H
class Animal {
private:
int age;
public:
Animal();
virtual ~Animal() {}
void setAge(int);
int getAge();
virtual void say() = 0;
};
#endif
Animal.cpp
#include "Animal.h"
Animal::Animal() {}
void Animal::setAge(int age) { this->age = age; }
int Animal::getAge() { return this->age; }
Dog.h
#ifndef DOG_H
#define DOG_H
#include "Animal.h"
class Dog : public Animal {
public:
Dog();
void say();
};
#endif
Dog.cpp
#include <iostream>
#include "Dog.h"
Dog::Dog() {}
void Dog::say() {
std::cout << "I am a dog" << std::endl;
}
Cat.h
#ifndef CAT_H
#define CAT_H
#include "Animal.h"
class Cat : public Animal {
public:
Cat();
void say();
};
#endif
Cat.cpp
#include <iostream>
#include "Cat.h"
Cat::Cat() {}
void Cat::say() {
std::cout << "I am a cat" << std::endl;
}
AnimalWrapper.h
#ifndef ANIMALWRAPPER_H
#define ANIMALWRAPPER_H
struct AnimalStruct;
#ifdef __cplusplus
extern "C" {
#endif
void initAnimal(struct AnimalStruct** as, int i, int type);
void setAge(struct AnimalStruct* as, int age);
void sayAge(struct AnimalStruct* as);
void deleteAnimal(struct AnimalStruct** as, int i);
#ifdef __cplusplus
};
#endif
#endif
AnimalWrapper.cpp
#include <iostream>
#include "AnimalWrapper.h"
#include "Animal.h"
#include "Dog.h"
#include "Cat.h"
struct AnimalStruct {
Animal* animal;
};
void initAnimal(struct AnimalStruct** animalArr, int i, int type) {
animalArr[i] = new struct AnimalStruct;
if(type == 0) {
animalArr[i]->animal = new Dog;
}
if(type == 1) {
animalArr[i]->animal = new Cat;
}
}
void setAge(struct AnimalStruct* as, int age) {
as->animal->setAge(age);
}
void sayAge(struct AnimalStruct* as) {
as->animal->say();
std::cout << "My age: " << as->animal->getAge() <<std::endl;
}
void deleteAnimal(struct AnimalStruct** animalArr, int i) {
delete animalArr[i];
animalArr[i] = NULL;
}
zoo.h
#ifndef ZOO_H
#define ZOO_H
#include "AnimalWrapper.h"
struct AnimalStruct** initZoo(int len);
void setAnimalAge(struct AnimalStruct** animalArr, int len);
void play(struct AnimalStruct** animalArr, int len);
void end(struct AnimalStruct** animalArr, int len);
#endif
zoo.c
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include "zoo.h"
struct AnimalStruct** initZoo(int len) {
struct AnimalStruct** animalArr = (struct AnimalStruct**)malloc(sizeof(struct AnimalStruct*) * len);
memset(animalArr, 0, sizeof(struct AnimalStruct*) * len);
int i = 0;
for(i = 0; i < len; i++) {
initAnimal(animalArr, i, i%2);
}
return animalArr;
}
void setAnimalAge(struct AnimalStruct** animalArr, int len) {
int i=0;
for(i = 0; i < len; i++) {
setAge(animalArr[i], (i+1)*10);
}
}
void play(struct AnimalStruct** animalArr, int len) {
int i = 0;
for(i = 0; i < len; i++) {
sayAge(animalArr[i]);
}
}
void end(struct AnimalStruct** animalArr, int len) {
int i = 0;
for(i = 0; i < len; i++) {
deleteAnimal(animalArr, i);
}
free(animalArr);
animalArr = NULL;
}
main.c
#include "zoo.h"
int main() {
int len = 10;
struct AnimalStruct** arr = initZoo(len);
setAnimalAge(arr, len);
play(arr, len);
end(arr, len);
return 0;
}
执行如下命令:
g++ -c Animal.cpp
g++ -c Dog.cpp
g++ -c Cat.cpp
g++ -c AnimalWrapper.cpp
gcc -c zoo.c
gcc Animal.o Dog.o Cat.o AnimalWrapper.o zoo.o main.c -o main -lstdc++
./main
执行结果如下所示:
I am a dog
My age: 10
I am a cat
My age: 20
I am a dog
My age: 30
I am a cat
My age: 40
I am a dog
My age: 50
I am a cat
My age: 60
I am a dog
My age: 70
I am a cat
My age: 80
I am a dog
My age: 90
I am a cat
My age: 100
4)C调用C++程序(C++程序涉及类、成员函数),使用C++ STL vector容器对C++中的类class进行包装,在C++程序中定义容器存储一组对象,C++程序对C程序暴露的接口函数仅传递包装后的对象地址(即对象在容器中的索引),此方法是对方法3)的改进,例子与3)相同
其中Animal.h、Animal.cpp、Dog.h、Dog.cpp、Cat.h、Cat.cpp与3)相同,不再赘述
AnimalWrapper.h
#ifndef ANIMALWRAPPER_H
#define ANIMALWRAPPER_H
struct AnimalStruct;
#ifdef __cplusplus
extern "C" {
#endif
void initAnimal(int type);
void setAge(int i, int age);
void sayAge(int i);
void deleteAnimal(int i);
#ifdef __cplusplus
};
#endif
#endif
AnimalWrapper.cpp
#include <iostream>
#include <vector>
#include "AnimalWrapper.h"
#include "Animal.h"
#include "Dog.h"
#include "Cat.h"
static std::vector<Animal*> animals;
void initAnimal(int type) {
Animal* animal = NULL;
if(type == 0) {
animal = new Dog;
}
if(type == 1) {
animal = new Cat;
}
animals.emplace_back(animal);
}
void setAge(int i, int age) {
animals[i]->setAge(age);
}
void sayAge(int i) {
animals[i]->say();
std::cout << "My age: " << animals[i]->getAge() <<std::endl;
}
void deleteAnimal(int i) {
delete animals[i];
animals[i] = NULL;
if(i == (animals.size()-1)) {
animals.clear();
}
}
zoo.h
#ifndef ZOO_H
#define ZOO_H
#include "AnimalWrapper.h"
void initZoo(int len);
void setAnimalAge(int len);
void play(int len);
void end(int len);
#endif
zoo.cpp
#include "zoo.h"
void initZoo(int len) {
int i = 0;
for(i = 0; i < len; i++) {
initAnimal(i%2);
}
}
void setAnimalAge(int len) {
int i = 0;
for(i = 0; i < len; i++) {
setAge(i, (i+1)*10);
}
}
void play(int len) {
int i = 0;
for(i = 0; i < len; i++) {
sayAge(i);
}
}
void end(int len) {
int i = 0;
for(i = 0; i < len; i++) {
deleteAnimal(i);
}
}
main.c
#include "zoo.h"
int main() {
int len = 10;
initZoo(len);
setAnimalAge(len);
play(len);
end(len);
return 0;
}
执行如下命令:
g++ -c Animal.cpp
g++ -c Dog.cpp
g++ -c Cat.cpp
g++ -c AnimalWrapper.cpp -std=c++11
gcc -c zoo.c
gcc Animal.o Dog.o Cat.o AnimalWrapper.o zoo.o main.c -o main -lstdc++
./main
执行结果如下所示:
I am a dog
My age: 10
I am a cat
My age: 20
I am a dog
My age: 30
I am a cat
My age: 40
I am a dog
My age: 50
I am a cat
My age: 60
I am a dog
My age: 70
I am a cat
My age: 80
I am a dog
My age: 90
I am a cat
My age: 100