I'm working on a large project in C, and I want to organize it using interface (.h) and implementation (.c) files, similar to many object-oriented languages such as Objective-C or Java. I am familiar with creating static libraries in C, but I think that doing so for my project is unnecessarily complex. How can I implement an interface/implementation paradigm in ANSI C? I'm primarily using GCC for compilation, but I'm aiming for strict adherence to ANSI C and cross-compiler compatibility. Thanks!
An interface is an empty shell, there are only the signatures of the methods, which implies that the methods do not have a body. The interface can't do anything. It's just a pattern. The implementation is the actual substance behind the idea, the actual definition of how the interface will do what we expect it to.
In order to create an interface, we need to create an abstract class which is having only pure virtual methods. In C++, Interfaces are also called pure abstract classes.
What Does Interface Mean? Interface, in C#, is a code structure that defines a contract between an object and its user. It contains a collection of semantically similar properties and methods that can be implemented by a class or a struct that adheres to the contract.
2) C# does not support "multiple inheritance" (a class can only inherit from one base class). However, it can be achieved with interfaces, because the class can implement multiple interfaces. Note: To implement multiple interfaces, separate them with a comma (see example below).
It sounds like you are already doing the right thing: good C code also organizes interfaces in .h-files and implementations in .c-files.
Example a.h file:
void f(int a);
Example a.c file:
#include "a.h"
static void helper(void) {...}
void f(int a) {... use helper()...}
Example main.c file:
#include "a.h"
int main(void) { f(123); return 0; }
You get modularity because helper-functions are not declared in headers so other modules dont know about them (you can declare them at the top of the .c
file if you want). Having this modularity reduces the number of recompiles needed and reduces how much has to be recompiled. (The linking has to be done every time though). Note that if you are not declaring helper-functions in the header then you are already pretty safe, however having the static
in front of them also hides them from other modules during linking so there is no conflict if multiple modules use the same helper-function-names.
If you are working with only primitive types then that is all you need to know and you can stop reading here. However if your module needs to work with a struct then it gets just a little more complicated.
Problematic example header b.h:
typedef struct Obj {
int data;
}*Obj;
Obj make(void);
void work(Obj o);
Your module wants to pass objects in and out. The problem here is, that internals are leaked to other modules that depend on this header. If the representation is changed to float data
then all using modules have to recompile. One way to fix this is to only use void*
. That is how many programs do it. However that is cumbersome because every function getting the void*
as argument has to cast it to Obj
. Another way is to do this:
Header c.h:
typedef struct Obj*Obj;
Obj make(void);
void work(Obj);
Implementation c.c:
#include "c.h"
typedef struct Obj {
int data;
}*Obj;
The reason why this works is, that Obj is a pointer (as opposed to a struct by value/copy). Other modules that depend on this module only need to know that a pointer is being passed in and out, not what it points to.
You must read something about OOP with non OOL such like http://www.cs.rit.edu/~ats/books/ooc.pdf. But, doing such you will never have strong OOP typing.
Please do yourself a favor and read C Interfaces and Implementations: Techniques for Creating Reusable Software
Here is a repository of mine that holds some libs written in C using the pattern of interfaces & implementation described in the book.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With