你想要更像这样的东西(在这里我将使用一个更有意义的例子):
C/C++ 头文件 - animal.h
#ifndef ANIMAL_H
#define ANIMAL_H
#ifdef __cplusplus
class Animal {
public:
Animal() : age(0), height(0) {}
Animal(int age, float height) : age(age), height(height) {}
virtual ~Animal() {}
int getAge();
void setAge(int new_age);
float getHeight();
void setHeight(float new_height);
private:
int age;
float height; // in metres!
};
#endif /* __cplusplus */
#ifdef __cplusplus
extern "C" {
#endif
struct animal; // a nice opaque type
struct animal *animal_create();
struct animal *animal_create_init(int age, float height);
void animal_destroy(struct animal *a);
void animal_setage(struct animal *a, int new_age);
void animal_setheight(struct animal *a, float new_height);
int animal_getage(struct animal *a);
float animal_getheight(struct animal *a);
#ifdef __cplusplus
}
#endif
#endif /* ANIMAL_H */
C++ 动物实现文件 - animal.cpp
#include "animal.h"
#define TO_CPP(a) (reinterpret_cast<Animal*>(a))
#define TO_C(a) (reinterpret_cast<animal*>(a))
void Animal::setAge(int new_age) { this->age = new_age; }
int Animal::getAge() { return this->age; }
void Animal::setHeight(float new_height) { this->height = new_height; }
float Animal::getHeight() { return this->height; }
animal *animal_create() {
animal *a = TO_C(new Animal);
return a;
}
animal *animal_create_init(int age, float height) {
animal *a = TO_C(new Animal(age, height));
return a;
}
void animal_destroy(animal *a) {
delete TO_CPP(a);
}
void animal_setage(animal *a, int new_age) {
TO_CPP(a)->setAge(new_age);
}
void animal_setheight(animal *a, float new_height) {
TO_CPP(a)->setHeight(new_height);
}
int animal_getage(animal *a) {
TO_CPP(a)->getAge();
}
float animal_getheight(animal *a) {
TO_CPP(a)->getHeight();
}
C 客户端代码 - main.c
#include "animal.h"
#include <stdio.h>
int main()
{
// 6'0" 25yo (perhaps a human? :P)
struct animal *a = animal_create(25, 1.83);
animal_setage(a, 26); // birthday
printf("Age: %d\nHeight: %f", animal_getage(a), animal_getheight(a));
animal_destroy(a);
return 0;
}
C++ 客户端代码 - main.cpp
#include "animal.h"
#include <iostream>
int main()
{
// 6'0" 25yo (perhaps a human? :P)
Animal* a = new Animal(25, 1.83);
a->setAge(26); // birthday
std::cout << "Age: " << a->getAge() << std::endl;
std::cout << "Height: " << a->getHeight();
delete a;
return 0;
}
因此,当您编译库时,您animal.cpp
使用 C++ 编译器进行编译。然后,您可以使用 C 代码链接到它,并使用这些animal_xxx
函数。
注意 和 的struct animal
使用Animal
。Animal
是一个普通的 C++ 类型。这正是它的样子。struct animal
,另一方面,是一种“不透明”的类型。这意味着您的 C 程序可以看到它的存在,并且可以拥有一个,但它不知道里面有什么。它所知道的是它有一个函数,它需要一个struct animal*
.
在真正的库中,您将希望有内存分配的自定义点。因此,假设这是 library libjungle
,您可能至少需要jungle_setmalloc
合理jungle_setfree
的默认值。然后,您可以设置全局new
和delete
inlibjungle
的 C++ 代码以使用这些用户定义的函数。