ANSI C中的接口/实现

时间:2014-10-05 17:34:48

标签: c ansi interface-implementation

我正在研究C中的一个大项目,我想使用接口(.h)和实现(.c)文件来组织它,类似于许多面向对象的语言,如Objective-C或Java。我熟悉在C中创建静态库,但我认为对我的项目这样做是不必要的复杂。如何在ANSI C中实现接口/实现范例?我主要使用GCC进行编译,但我的目标是严格遵守ANSI C和交叉编译器的兼容性。谢谢!

3 个答案:

答案 0 :(得分:7)

听起来你已经正在做正确的事:好的C代码在.h文件中组织接口并在.c文件中实现。

示例a.h文件:

void f(int a);

示例a.c文件:

#include "a.h"
static void helper(void) {...}
void f(int a) {... use helper()...}

main.c文件示例:

#include "a.h"
int main(void) { f(123); return 0; }

你得到了模块化,因为helper-functions没有在头文件中声明,因此其他模块不了解它们(如果需要,可以在.c文件的顶部声明它们)。具有此模块性可减少所需的重新编译次数,并减少必须重新编译的。 (链接必须每次都完成)。请注意,如果您没有在标头中声明辅助函数,那么您已经非常安全了,但是在它们前面有static也会在链接期间将它们隐藏在其他模块中,因此如果多个模块使用相同的辅助函数名称。

如果你只使用原始类型,那么这就是你需要知道的所有内容,你可以在这里停止阅读。但是,如果您的模块需要使用结构,那么它会变得更复杂。

有问题的示例标题b.h:

typedef struct Obj {
    int data;
}*Obj;
Obj make(void);
void work(Obj o);

您的模块想要传入和传出对象。这里的问题是,内部泄漏到依赖于此标头的其他模块。如果表示更改为float data,那么所有使用模块都必须重新编译。解决此问题的一种方法是仅使用void*。这就是有多少程序。然而,这很麻烦,因为将void*作为参数的每个函数都必须将其强制转换为Obj。另一种方法是这样做:

标题c.h:

typedef struct Obj*Obj;
Obj make(void);
void work(Obj);

实施c.c:

#include "c.h"
typedef struct Obj {
    int data;
}*Obj;

这个工作的原因是,Obj是一个指针(与value / copy的结构相反)。依赖于此模块的其他模块只需要知道指针正在传入和传出,而不是指向它。

答案 1 :(得分:0)

您必须阅读有关非OOL的OOP,例如http://www.cs.rit.edu/~ats/books/ooc.pdf。 但是,这样做你永远不会有强大的OOP输入。

答案 2 :(得分:0)

请帮自己一个忙,并阅读C Interfaces and Implementations: Techniques for Creating Reusable Software

这里是a repository of mine,它使用接口模式来保存一些用C语言编写的库。本书中描述的实现。