Skip to content

Instantly share code, notes, and snippets.

@laindir
Created October 8, 2014 17:05
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save laindir/53448acc7d18f1daa048 to your computer and use it in GitHub Desktop.
Save laindir/53448acc7d18f1daa048 to your computer and use it in GitHub Desktop.
An example of using interface types in C
#ifndef container_of
#include <stddef.h>
#define container_of(ptr, type, member) ((type *)(((char *)ptr) - offsetof(type, member)))
#endif
#include "file_logger.h"
#include "container_of.h"
#include <stdio.h>
static int
file_logger_log(struct ilogger *ilogger, struct ilogrecord *record)
{
struct file_logger *this = container_of(ilogger, struct file_logger, ilogger);
if(fprintf(this->file, "%s\n", record->format(record)) < 0)
{
return -1;
}
else
{
return 0;
}
}
void
file_logger_init(struct file_logger *this, FILE *file)
{
this->ilogger.log = file_logger_log;
this->file = file;
}
struct file_logger
file_logger_new(FILE *file)
{
struct file_logger new;
file_logger_init(&new, file);
return new;
}
#ifndef FILE_LOGGER_H
#define FILE_LOGGER_H
#include "ilogger.h"
#include <stdio.h>
struct file_logger
{
struct ilogger ilogger;
FILE *file;
};
void
file_logger_init(struct file_logger *this, FILE *file);
struct file_logger
file_logger_new(FILE *file);
#endif
#ifndef ILOGGER_H
#define ILOGGER_H
struct ilogrecord
{
const char *(*format)(struct ilogrecord *this);
};
struct ilogger
{
int (*log)(struct ilogger *this, struct ilogrecord *record);
};
#endif
#include "ilogger.h"
#include "string_logrecord.h"
#include "file_logger.h"
int
main(void)
{
struct file_logger fl = file_logger_new(stdout);
struct string_logrecord slr = string_logrecord_new("Hello, World!");
struct ilogger *logger = &fl.ilogger;
struct ilogrecord *logrecord = &slr.ilogrecord;
logger->log(logger, logrecord);
return 0;
}
CFLAGS=-Wall -Wextra -pedantic -ansi -g
main: file_logger.o string_logrecord.o
main.o: ilogger.h file_logger.h string_logrecord.h
file_logger.o: ilogger.h file_logger.h
string_logrecord.o: ilogger.h string_logrecord.h
#include "string_logrecord.h"
#include "container_of.h"
static const char *
string_logrecord_format(struct ilogrecord *ilogrecord)
{
struct string_logrecord *this = container_of(ilogrecord, struct string_logrecord, ilogrecord);
return this->text;
}
void
string_logrecord_init(struct string_logrecord *this, const char *text)
{
this->ilogrecord.format = string_logrecord_format;
this->text = text;
}
struct string_logrecord
string_logrecord_new(const char *text)
{
struct string_logrecord new;
string_logrecord_init(&new, text);
return new;
}
#ifndef STRING_LOGRECORD_H
#define STRING_LOGRECORD_H
#include "ilogger.h"
struct string_logrecord
{
struct ilogrecord ilogrecord;
const char *text;
};
void
string_logrecord_init(struct string_logrecord *this, const char *text);
struct string_logrecord
string_logrecord_new(const char *text);
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment