2014-10-05 20 views
5

Ich arbeite an einem großen Projekt in C, und ich möchte es mit Schnittstellen (. H) und Implementierung (. C) -Dateien, ähnlich wie viele objektorientierte Sprachen wie Objective organisieren -C oder Java. Ich bin vertraut mit dem Erstellen von statischen Bibliotheken in C, aber ich denke, dass dies für mein Projekt unnötig komplex ist. Wie kann ich ein Schnittstellen-/Implementierungsparadigma in ANSI C implementieren? Ich verwende hauptsächlich GCC für die Kompilierung, aber ich strebe die strikte Einhaltung der Kompatibilität mit ANSI C und Cross-Compiler an. Vielen Dank!Schnittstelle/Implementierung in ANSI C

+0

Sprechen Sie eigentlich über OOP in C? –

+0

Nein, ich bin im Grunde auf der Suche nach einer Möglichkeit, Funktionsdefinitionen von den inneren Funktionen dieser Funktionen zu trennen und auch eine Methode, um verwandte Funktionen und solche zusammen (wie math.h, zum Beispiel) zu gruppieren. Ich möchte keine Bibliothek verwenden, da ich die Funktionen in anderen Programmen nicht wiederverwenden werde. Außerdem muss ich häufig die Funktionalität ändern. – user2105505

+0

Funktion in der .h-Datei statisch machen, und sie wäre nur in der .c-Datei sichtbar; –

Antwort

5

Es klingt wie Sie bereits das Richtige zu tun sind: gut C-Code auch Schnittstellen in .h-Dateien und Implementierungen in .c-Dateien organisiert.

Beispiel ah Datei:

void f(int a); 

Beispiel ac Datei:

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

Beispiel main.c Datei:

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

Sie Modularität erhalten, weil Helfer-Funktionen, die nicht erklärt werden Header, so dass andere Module nicht über sie wissen (Sie können sie an der Spitze derdeklarieren 0 Datei, wenn Sie wollen). Diese Modularität reduziert die Anzahl der erforderlichen Neukompilierungen und reduziert , wie viel neu kompiliert werden muss. (Die Verknüpfung muss jedoch jedes Mal durchgeführt werden). Beachten Sie, dass wenn Sie keine Hilfsfunktionen in der Kopfzeile deklarieren, Sie schon ziemlich sicher sind. Wenn Sie die static davor haben, werden sie auch während der Verlinkung von anderen Modulen ausgeblendet, so dass es keinen Konflikt gibt, wenn mehrere Module die gleiche Hilfsfunktion verwenden -Namen.

Wenn Sie nur mit primitiven Typen arbeiten, dann ist das alles, was Sie wissen müssen, und Sie können hier aufhören zu lesen. Wenn Ihr Modul jedoch mit einer Struktur arbeiten muss, wird es nur ein wenig komplizierter.

Problematische Beispiel Kopf b.h:

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

Ihr Modul will Objekte in und aus führen. Das Problem hierbei ist, dass Interna an andere Module weitergegeben werden, die von diesem Header abhängen. Wenn die Darstellung in float data geändert wird, müssen alle Module neu kompiliert werden. Eine Möglichkeit, dies zu beheben, besteht darin, nur void* zu verwenden. So viele Programme machen es. Dies ist jedoch umständlich, da jede Funktion, die das void* als Argument erhält, es in Obj umwandeln muss. Eine andere Möglichkeit ist, dies zu tun:

Header-ch:

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

Implementierung cc:

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

Der Grund, warum dies funktioniert, ist, dass Obj ist ein Zeiger (im Gegensatz zu einer Struktur entgegengesetzt durch Wert/Kopie). Andere Module, die von diesem Modul abhängen, müssen nur wissen, dass ein Zeiger ein- und ausgegeben wird, nicht, worauf er zeigt.

+0

Vielen Dank für Ihre klare Antwort. Kann dies mit einem Befehl in GCC getan werden? Der Aufruf von "gcc main.c" führt zu einem undefinierten Symbolfehler. – user2105505

+0

Sie sollten 'gcc -c filename.c' für jede c-Datei aufrufen. Jeder von ihnen erzeugt eine O-Datei (Modul). Am Ende rufst du 'gcc * .o' an, was sie alle miteinander verbindet. Wenn Sie nur 'b.c' geändert haben, müssen Sie nur noch neu kompilieren (' b.o') und dann erneut verlinken. (Die unveränderten C-Dateien müssen nicht erneut kompiliert werden.) –

+0

@ user2105505 Auch dies wird normalerweise durch ein Makefile automatisiert. Dazu müssen Sie nur "make" an der Befehlszeile eingeben und es wird auswählen, welche C-Dateien neu kompiliert werden, und es verbindet dann das Programm miteinander. –

1

Sie müssen etwas über OOP mit nicht OOL wie http://www.cs.rit.edu/~ats/books/ooc.pdf lesen. Aber so werden Sie nie starke OOP tippen.

+1

Auch das macht dich wahnsinnig;) –

+0

Das ist ein bisschen übertrieben, aber du wirst mindestens starke Disziplin brauchen (das kann dich verrückt machen). –

+2

"Ich hatte Spaß zu entdecken, dass ANSI-C eine vollständige objektorientierte Sprache ist" - hörte auf, dort zu lesen. Hilarious. Ja, man kann OOP-Muster mit MASSIVem Aufwand simulieren, aber das ist ziemlich sinnlos und ineffizient, auch: das würde im Grunde genommen ein Rad neu erfinden. Es gibt keine Notwendigkeit für OO-Muster in C. C ist eine Sprache auf niedriger Ebene, die OO dazu zwingt, Probleme hervorzurufen - deshalb wurde Obj-C erfunden. – specializt