Archive for the ‘ Development ’ Category

Object-Oriented C

Although C is regarded primarily as a procedural language, it is entirely possible to write C code structured in a way similar to code written in object-oriented languages such as C++.

Now, of course, you could go all out and write truely object-oriented C, complete with inheritance, type checking, and the like. But that’s not what we’re going to be doing here.  Instead of recreating the complete functionality of object-orientation, we’re going to look at how to write pseudo-object-oriented code in C. The key is that the code itself is still procedural, but organized in a way such that it can be used in an OO fashion.  The technique itself is very simple, and when used properly it can make code management much easier.

The first thing to address is data encapsulation.  How do we define a new data type so that the rest of the program is able to use it without knowing about its internal structure?

Doing this is rather easy.  In our header file we tell the compiler that the structure will be defined elsewhere by simply declaring the struct without defining it:

struct String;
typedef struct String String;    /* typedef'd for convenience */

Then, in our source file, we define the actual structure:

struct String {
    unsigned char *str;
    unsigned int len;
};

Now, whenever we include string.h in our program, we have access to the String type, that is, we can declare String variables and pointers, but the internal data of the struct is hidden from us. Voila – encapsulation!

The next step is to distinguish the scope of our type’s methods. This is equally as simple, and we’ll start by establishing a few simple naming conventions that will allow us to simulate the scope of functions related to our data type.

For public methods, we’ll prefix the function with the name of the type and an underscore.  For example, if we wanted to create a public method for String called append(), then the corresponding function would be String_append().

For private methods, we’ll prefix the function name with only an underscore.  For example, if we wanted to add a private method to String called resize(), the corresponding function would be _resize().

These conventions help us to visually distinguish which methods should be called by other parts of the program and which ones should be limited for use by only the module containing the data type.

But let’s not rely on these conventions alone.  Where we place our function prototypes is just as important as how we name them. Since we want to make our public methods available to other parts of the program, we place their prototypes in the header file for our module.  This grants access to these functions to any file that includes our header, just like we did with the structure.

Our private methods, however, are declared in the source file as static methods.  This ensures that only other functions within the module will be able to access them.

Let’s create a data type called String to illustrate how the technique works.  We’ll start by defining our header file, mystring.h:

#ifndef STRING_H
#define STRING_H

/* declare the struct (but don't define it!) */
struct String;
typedef struct String String;

/* declare some public methods */
String* String_new( const char *init );
void String_delete( String *str );
void String_append( String *str, const char *other );

#endif

Since the code we’re writing isn’t truely object-oriented (and we’re not messing around with all sorts of function pointers), we need a way for the functions to know which object they are acting upon. For this reason, we pass a pointer to the object as the first argument of each function. In an actual object-oriented language, a method call would look like this:

obj.method(arg1, arg2, ...);

In our pseudo-object-oriented code, the method call looks like this:

method(obj, arg1, arg2, ...);

Now let’s move on to our source file, mystring.c, where we will define the struct, declare our private methods, and define both our public and private methods.

#include <stdlib.h>
/* string.h and strings.h are included for
   strlen() and strlcpy(), respectively. */
#include <string.h>
#include <strings.h>
#include "mystring.h"

/* define the struct */
struct String {
    unsigned char *str;
    unsigned int len;
};

/* declare private methods */
static void _resize( String *str, const unsigned int newSize );

/* define private methods */
void _resize( String *str, const unsigned int newSize ) {
    if( newSize != str->len ) {
        str->str = realloc(str->str, newSize);
        str->len = newSize;
    }
}

/* define public methods */
String* String_new( const char *init ) {
    String *retval = malloc(sizeof(String));
    retval->len = strlen(init);
    retval->str = malloc(sizeof(char) * retval->len);
    strlcpy(retval->str, init, retval->len);
}

void String_delete( String* str ) {
    free(str->str);
    free(str);
}

void String_append( String* str, const char *other ) {
    int i, oldLen = str->len;
    _resize(str, strlen(other));
    for( i = oldLen; i < str->len; ++i ) {
        str->str[i] = other[oldLen - i];
    }
}

That’s essentially all there is to it. Other C modules in the program will be able to declare and create String objects, but will not have access to their internal variables and will only be allowed to call the public methods declared in the header file.

On a final note, if you consider yourself a proficient C programmer, I highly recommend checking out the book I liked to at the beginning of this article.  It’s an excellent read and gives a truely insightful look into the inner workings of many of the object-oriented language constructs we’ve come to rely on.

Creating Custom printf() Wrappers

Sitting at my desk hacking away at a project in C, I began to think back to the good ol’ days of last summer when I was knee-deep in Flex work. Now don’t get me wrong, I like lower-level C code as much as the next guy… who… well, likes lower-level C code. But there were certain niceties about ActionScript 3 that I just miss in times like these.  One of those, of course, was trace().

Sure, printf() works fine for quickly spitting out some debugging information.  But golly, it sure would be nice to add a custom prefix to those messages, maybe even have them print to stderr while I’m at it. My desire for my buddy trace() got the best of me, and after some brief searching, I found a way to create my own custom printf() wrapper functions.

The technique is rather simple.  Declare a function that accepts a format string and a varying number of further arguments.  Pass said string and arguments to fprintf.  Do anything else desired before and after.

Here’s how to do it in C/C++:

#include <stdio.h>
#include <stdarg.h>

void trace( const char* format, ... ) {
    va_list args;
    fprintf( stderr, "[Debug] " );
    va_start( args, format );
    vfprintf( stderr, format, args );
    va_end( args );
    fprintf( stderr, "\n" );
}

And here’s the PHP equivalent:

function trace() {
    $args = func_get_args();
    $format = array_shift( $args );
    printf( '[Debug] ' );
    vprintf( $format, $args );
    printf( "\n" );
}

Not too shabby.  I ended up creating three different functions for this particular project: info(), error(), and trace().  The nice part is that I can now conditionally control whether or not these functions actually output anything via command line arguments. All that’s left is to add macros to automatically add the filename and line numbers to the output.

I whipped up a couple of tutorials over at Ozzu coving this in more detail. The C and PHP versions of the tutorial can be found below, respectively.
Writing a Custom printf() Wrapper Function in C
Writing a Custom printf() Wrapper Function in PHP

Update:
It turns out I wanted the filename and line numbers afterall, so I went ahead an added a macro (in C) to get the job done. Change the name of the function to _trace() and add two more arguments, so that your function now looks like this:

#define trace(...) _trace(__FILE__, __LINE__, __VA_ARGS__)

void _trace( char* filename, int line, const char* format, ... ) {
    va_list args;
    fprintf( stderr, "[%s:%d] " );
    va_start( args, format );
    vfprintf( stderr, format, args );
    va_end( args );
    fprintf( stderr, "\n" );
}

Every call to trace() will now print out the filename and line number of the trace call, followed by the formatted message.

nf – A Simple Number Format Utility

One of the projects I’m working on requires me to switch between decimal and hexadecimal formats for values that I’m dealing with.  I found myself using Google quite a bit to convert between number formats, but after a day or two of constantly opening my web browser to do this, it was getting to be a pain.

I decided to write a quick utility that I could use from the command line to view a number in all three formats.  Hence, I present you with nf, short for ‘number format’:

int main( int argc, char* argv[] ) {
    if( argc != 2 ) {
        printf( "usage: %s <number>\n", argv[0] );
        exit( 0 );
    }
    long int num = strtol( argv[1], 0x0, 0 );
    printf( "DEC: %ld\nOCT: %lo\nHEX: %lX\n", num, num, num );
}

Just compile it with your favorite C compiler, toss it in /usr/local/bin (or any other directory of your choice in your PATH), and you’re good to go. It generates output like the following:

$ nf 42
DEC: 42
OCT: 52
HEX: 2A

The argument passed to nf can be in decimal, octal, or hex format; strtol() automatically determines which format you’re using. Decimal numbers begin with any digit 1-9, octal numbers begin with a 0, and hex numbers begin with 0x. Thus, the utility can be used to convert between all three formats.