Интерфейс / реализация в ANSI C

Я работаю над большим проектом в C, и я хочу организовать это с помощью интерфейса (.H) и реализацию (.c) файлы, подобные многим объектно-ориентированным языкам, таким как Objective-C или Java. Я знаком с созданием статических библиотек в C, но я думаю, что это для моего проекта излишне сложно. Как я могу реализовать парадигму интерфейса / реализации в ANSI C? Я в основном использую GCC для компиляции, но я стремлюсь к строгому соблюдению ANSI C и кросс-компилятора совместимость. Спасибо!

3 ответов


похоже, что ты уже делать правильные вещи: хороший код 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; }

вы получаете модульность, потому что вспомогательные функции не объявляются в заголовках, поэтому другие модули не знают о них (вы можете объявить их в верхней части .c файл, если вы хотите). Наличие этой модульности уменьшает количество необходимых перекомпиляций и уменьшает сколько должен быть перекомпилирован. (The связь должно быть сделано каждый раз, хотя). Обратите внимание, что если вы не объявляете вспомогательные функции в заголовке, то вы уже довольно безопасны, однако с static перед ними также скрывает их от других модулей во время связывания, поэтому нет конфликта, если несколько модулей используют одно и то же имена вспомогательных функций.

если вы работаете только с примитивными типами, то это все, что вам нужно знать, и вы можете прекратить читать здесь. Однако, если ваш модуль должен работать со структурой, он становится немного сложнее.

проблемный пример заголовка b.h:

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

ваш модуль хочет передавать объекты внутрь и наружу. Проблема здесь в том, что внутренние данные просачиваются в другие модули, которые зависят от этого заголовка. Если представление изменено к float data затем все используемые модули должны перекомпилироваться. Один из способов исправить это - использовать только void*. Вот сколько программ это делают. Однако это громоздко, потому что каждая функция получает void* как аргумент должен привести его к Obj. Другой способ сделать это:

заголовок c.ч:

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

Си.с:

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

причина, по которой это работает, заключается в том, что Obj является указателем (в отличие от структуры по значению/копии). Другие модули, которые зависят в этом модуле нужно только знать, что указатель передается и выходит, а не то, на что он указывает.


вы должны прочитать что-то об ООП с не оол, такие как http://www.cs.rit.edu / ~ats / книги / ooc.pdf. Но, делая это, у вас никогда не будет сильного ввода ООП.


пожалуйста, сделайте себе одолжение и читать C интерфейсы и реализации: методы создания многоразового программного обеспечения

здесь мое хранилище который содержит некоторые библиотеки, написанные на C, используя шаблон интерфейсов и реализации, описанный в книге.