Question

In OO languages, we have ways to enforce a standardisation of interfaces across the number of libraries:

   Interface
      |------Implementation A
      |
      \------Implementation B

I have thoughts to do something like this:

  Interface.h
      |------Implementation A.c
      |
      \------Implementation B.c

where Interface.h contains:

  • functionStandard_A()
  • functionStandard_B()

What would be the best practice in C to achieve something like this?

Was it helpful?

Solution

An "interface" in C can be created by defining a struct of function pointers. Each "concrete implementation" would present itself through an instance of this struct, having initialised the function pointers within it to point to the functions within that implementation.

For example, imagine creating an modem driver interface so that different C modem drivers have a standard set of functions. I use modem drivers because they're a good example from an application I happen to be working on now.

Example of interface:

typedef struct modem_interface
{
    void (*start_call)(void);
    void (*hang_up)(void);
    ...
}

You might have two different modem drivers, modem_A.c and modem_B.c, each with their own functions to handle starting a call, hanging up a call, and other operations. Each driver creates an instance of modem_interface and inialises it so that the function pointers point to its functions.

For example, within modem_A.c:

...
modem_interface modem_A_interface;
modem_interface.start_call = &modem_A_start_call; 
...

Somewhere else in the application, you might grab a pointer to modem A's 'interface' struct and call standard functions ("methods") on it as they are defined originally in modem_interface:

...
modem_A->start_call();
modem_A->hang_up();
...

This way, you can have any number of modem drivers, but the application can work with any of them simply through a modem_interface pointer. For example:

void application_starts_a_call( modem_interface* required_modem )
{
    required_modem->start_call();
    ...
}


// elsewhere:
application_starts_a_call( &modem_A );
application_starts_a_call( &modem_B );

Quickly typed out before I rush out of the door so corrections welcomed. Hope it illustrates the concept well enough.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top