C、C++程序相互调用的四种情况

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

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值