Very Simple, Minimalist Technique For OOP in C...

Discussion in 'C Programming' started by Chris Thomasson, Jun 21, 2007.

  1. Here is the example code:

    - http://appcore.home.comcast.net/vzoom/example/interface.zip


    which is an analog of the following technique:

    - http://groups.google.com/group/comp.lang.c/msg/6cf857051ca4029b


    It's definitely not full-blown OOP is any sense of the term, however imho, I
    think it could be fairly useful in certain scenarios... Now, let me try to
    briefly describe it:

    The provided example shows how a minimalist abstract interface for a "shape"
    object might look. It also includes an implementation of simple circle and
    square objects that are compatible with the abstract shape interface. If you
    want to try and add another shape to get a feel for how "cumbersome" the
    interface method is, well, here is a quick example of that:


    <pseudo-code for adding, lets say, a triangle>
    __________________________

    triangle.h
    __________________
    /* Put include guard here */

    #include "ishape.h"

    /* Return values that are non-zero indicate error's */

    /* Create a new triangle */
    extern int Triangle_Create(IShape_t* const, /* [triangle params] */);



    triangle.c
    __________________
    #include "triangle.h"


    typedef struct Triangle_s Triangle_t;

    struct Triangle_s {
    /* [triangle members] */
    };


    static int Triangle_IObject_Destroy(void* const);
    static int Triangle_IObject_Status(void* const);
    static int Triangle_IShape_Draw(void* const);


    /* Triangle IShape Interface VTable */
    static IShape_VTable_t const Triangle_IShape_VTable = {
    Triangle_IObject_Destroy,
    Triangle_IObject_Status,
    Triangle_IShape_Draw
    };


    /* Triangle Interface Functions */
    int
    Triangle_Create(
    IShape_t* const IThis,
    /* [triangle params] */) {
    Triangle_t* const This = malloc(sizeof(*This));
    if (This) {
    /* [init This triangle] */
    IOBJECT_INIT(IThis, This, &Triangle_IShape_VTable);
    return 0;
    }
    return -1;
    }


    /* Triangle IObject Interface Functions */
    int
    Triangle_IObject_Destroy(void* const ThisState) {
    Triangle_t* const This = ThisState;
    free(This);
    return 0;
    }


    int
    Triangle_IObject_Status(void* const ThisState) {
    Triangle_t* const This = ThisState;
    /* [determine This triangle state; this is optional] */
    return 0;
    }


    /* Triangle IShape Interface Functions */
    int
    Triangle_IShape_Draw(void* const ThisState) {
    Triangle_t* const This = ThisState;
    /* [draw This triangle] */
    return 0;
    }
    __________________________




    IMHO, that should be "fairly" straight forward... Now, here is how you could
    use your Triangle:
    __________________________

    #include "triangle.h"

    int Example(void) {
    IShape_t MyShape;

    int rStatus = Triangle_Create(&MyShape, /* [triangle params] */);
    if (! rStatus) {

    rStatus = IShape_Draw(&MyShape);
    if (rStatus) {

    rStatus = IObject_Status(&MyShape);
    }

    rStatus = IObject_Destroy(&MyShape);
    }

    return rStatus;
    }
    __________________________


    I was wondering if you have come across any superior methods for very basic
    OOP in C?


    Any thoughts? Is this method total crap?

    ;^)


    Thanks.
    Chris Thomasson, Jun 21, 2007
    #1
    1. Advertising

  2. "Chris Thomasson" <> wrote in message
    news:...
    [...]

    > It's definitely not full-blown OOP is any sense of the term, however imho,
    > I think it could be fairly useful in certain scenarios... Now, let me try
    > to briefly describe it:


    [...]

    Actually, I think the example code should be fairly self-explanatory...
    Chris Thomasson, Jun 21, 2007
    #2
    1. Advertising

  3. "Chris Thomasson" <> wrote in message
    news:...
    > Here is the example code:
    >
    > - http://appcore.home.comcast.net/vzoom/example/interface.zip
    >
    >
    > which is an analog of the following technique:
    >
    > - http://groups.google.com/group/comp.lang.c/msg/6cf857051ca4029b
    >
    >
    > It's definitely not full-blown OOP is any sense of the term, however imho,
    > I think it could be fairly useful in certain scenarios...


    [...]

    I just remembered that a library called Nobel uses same basic technique:


    You can create an abstract interface in C by declaring a vtable structure
    and the interface structure self. First we setup a type for the VTable's
    first parameter (e.g., 'this' in c++):
    _______________
    typedef void* IObject_This_t;
    typedef IObject_This_t const VTable_This_t;
    _______________




    Now, lets say that our new interface will be for a thread/process
    mutual-exclusion synchronization object. So, we need to declare the
    following structs:
    _______________
    typedef struct IMutex_s IMutex_t;
    typedef struct IMutex_VTable_s IMutex_VTable_t;
    _______________



    And then we define the struct for our mutex interface:
    _______________
    struct IMutex_s {
    IObject_This_t This;
    IMutex_VTable_t const *VTable;
    };

    /*Take note of the names of the members of IMutex_t: (This, VTable). Its
    import that you keep the names you choose consistent because they are going
    to be depended upon. More on that later.
    */
    _______________




    An abstract mutex interface needs at least the following abstract functions
    (Destroy, Lock, Unlock), so we define the following vtable struct:
    _______________
    struct IMutex_VTable_s {
    int (*fp_IObject_Destroy) (VTable_This_t);
    int (*fp_Lock) (VTable_This_t);
    int (*fp_Unlock) (VTable_This_t);

    /*Take note of the names of the members of IMutex_VTable_t:
    (fp_IObject_Destroy, fp_Lock, fp_Unlock). Its import that you keep the names
    you choose consistent because they are going to be depended upon. More on
    that later.
    */
    };
    _______________




    Now, we need to define the abstract interface that makes use of all the
    above. We start be defining a helper function and an abstract function that
    can init/destroy any object:
    _______________
    #define IObject_Initialize(__IThis, __ThisPtr, __VTablePtr) \
    (__IThis)->This = (__ThisPtr); \
    (__IThis)->VTable = (__VTablePtr)

    #define IObject_Destroy(__IThis) \
    (__IThis)->VTable->fp_IObject_Destroy((__IThis)->This)
    _______________



    Now we define the abstract functions of IMutex_t:
    _______________
    #define IMutex_Lock(__IThis) \
    (__IThis)->VTable->fp_Lock((__IThis)->This)

    #define IMutex_Unlock(__IThis) \
    (__IThis)->VTable->fp_Unlock((__IThis)->This)
    _______________




    Stick all the above in a header file called (imutex.h) or whatever and
    that's it for the abstract interface part. Now you create an object that
    makes use of the interface:


    your_mutex.h
    _______________
    /* include guard */
    #include "imutex.h"
    extern int Your_Mutex_Create(IMutex_t* const);



    your_mutex.c
    _______________
    #include "your_mutex.h"
    #include <stdlib.h> /* malloc/free */


    /* declare/define your mutexs impl struct */
    typedef struct Your_Mutex_s Your_Mutex_t;
    typedef Your_Mutex_t* const Your_Mutex_This_t;

    struct Your_Mutex_s {
    /* [impl specific mutex data] */
    };


    /* declare your mutexs interface functions */
    static int Your_Mutex_IObject_Destroy(VTable_This_t);
    static int Your_Mutex_Lock(VTable_This_t);
    static int Your_Mutex_Unlock(VTable_This_t);


    /* define your mutex interface vtable */
    static IMutex_VTable_t const Your_Mutex_VTable = {
    Your_Mutex_IObject_Destroy,
    Your_Mutex_Lock,
    Your_Mutex_Unlock
    };


    /* define mutex create function */
    int Your_Mutex_Create(IMutex_t* const IThis) {
    Your_Mutex_This_t This = malloc(sizeof(*This));
    if (This) {
    /* [init impl This specific mutex data] */

    /* init the IThis interface */
    IObject_Initialize(IThis, This, &Your_Mutex_VTable);
    return 0;
    }
    return -1;
    }


    /* define mutex object destroy */
    int Your_Mutex_IObject_Destroy(VTable_This_t ThisState) {
    Your_Mutex_This_t This = ThisState;
    /* [teardown impl This specific mutex data] */
    free(This);
    return -1;
    }


    /* define mutex interface */
    int Your_Mutex_Lock(VTable_This_t ThisState) {
    Your_Mutex_This_t This = ThisState;
    /* [lock impl This specific mutex] */
    return -1;
    }


    int Your_Mutex_Unlock(VTable_This_t ThisState) {
    Your_Mutex_This_t This = ThisState;
    /* [unlock impl This specific mutex] */
    return -1;
    }
    _______________


    That's it for the interface and impl... Now you can use it like:


    _______________
    #include "your_mutex.h"


    int Locked_Callback(
    IMutex_t* const IThis,
    int (*fp_Callback) (void*, IMutex* const),
    void *CallbackState) {

    int rStatus = IMutex_Lock(IThis);
    if (! rStatus) {

    rStatus = fp_Callback(CallbackState, IThis);
    if (! rStatus) {
    rStatus = IMutex_Unlock(IThis);
    }
    }

    return rStatus;
    }



    static IMutex_t The_Lock;


    int Critical_Section(void *ThisState, IMutex_t* const Lock) {
    /* [your in a critical-section locked by 'Lock'] */
    return 0;
    }


    void Some_Threads(/* [...] */) {
    /* [...] */
    Locked_Callback(&The_Lock, Critical_Section, /* [ptr to state */);
    }


    int main(void) {
    int rStatus = Your_Mutex_Create(&The_Lock);
    if (! rStatus) {
    /* [create Some_Threads] */
    }
    return rStatus ;
    }
    _______________



    Well, barring any typos, that's about it. ;^)
    Chris Thomasson, Jun 21, 2007
    #3
  4. > int main(void) {
    > int rStatus = Your_Mutex_Create(&The_Lock);
    > if (! rStatus) {
    > /* [create Some_Threads] */


    /* [join threads] */

    rStatus = IObject_Destroy(&The_Lock);

    > }
    > return rStatus ;
    > }
    > _______________
    Chris Thomasson, Jun 21, 2007
    #4
  5. On Jun 21, 5:30 am, "Chris Thomasson" <> wrote:
    > Here is the example code:
    >
    > -http://appcore.home.comcast.net/vzoom/example/interface.zip
    >
    > which is an analog of the following technique:
    >
    > -http://groups.google.com/group/comp.lang.c/msg/6cf857051ca4029b
    >
    > It's definitely not full-blown OOP is any sense of the term, however imho, I
    > think it could be fairly useful in certain scenarios... Now, let me try to
    > briefly describe it:
    >
    > The provided example shows how a minimalist abstract interface for a "shape"
    > object might look. It also includes an implementation of simple circle and
    > square objects that are compatible with the abstract shape interface. If you
    > want to try and add another shape to get a feel for how "cumbersome" the
    > interface method is, well, here is a quick example of that:
    >
    > <pseudo-code for adding, lets say, a triangle>
    > __________________________
    >
    > triangle.h
    > __________________
    > /* Put include guard here */
    >
    > #include "ishape.h"
    >
    > /* Return values that are non-zero indicate error's */
    >
    > /* Create a new triangle */
    > extern int Triangle_Create(IShape_t* const, /* [triangle params] */);
    >
    > triangle.c
    > __________________
    > #include "triangle.h"
    >
    > typedef struct Triangle_s Triangle_t;
    >
    > struct Triangle_s {
    > /* [triangle members] */
    >
    > };
    >
    > static int Triangle_IObject_Destroy(void* const);
    > static int Triangle_IObject_Status(void* const);
    > static int Triangle_IShape_Draw(void* const);
    >
    > /* Triangle IShape Interface VTable */
    > static IShape_VTable_t const Triangle_IShape_VTable = {
    > Triangle_IObject_Destroy,
    > Triangle_IObject_Status,
    > Triangle_IShape_Draw
    >
    > };
    >
    > /* Triangle Interface Functions */
    > int
    > Triangle_Create(
    > IShape_t* const IThis,
    > /* [triangle params] */) {
    > Triangle_t* const This = malloc(sizeof(*This));
    > if (This) {
    > /* [init This triangle] */
    > IOBJECT_INIT(IThis, This, &Triangle_IShape_VTable);
    > return 0;
    > }
    > return -1;
    >
    > }
    >
    > /* Triangle IObject Interface Functions */
    > int
    > Triangle_IObject_Destroy(void* const ThisState) {
    > Triangle_t* const This = ThisState;
    > free(This);
    > return 0;
    >
    > }
    >
    > int
    > Triangle_IObject_Status(void* const ThisState) {
    > Triangle_t* const This = ThisState;
    > /* [determine This triangle state; this is optional] */
    > return 0;
    >
    > }
    >
    > /* Triangle IShape Interface Functions */
    > int
    > Triangle_IShape_Draw(void* const ThisState) {
    > Triangle_t* const This = ThisState;
    > /* [draw This triangle] */
    > return 0;}
    >
    > __________________________
    >
    > IMHO, that should be "fairly" straight forward... Now, here is how you could
    > use your Triangle:
    > __________________________
    >
    > #include "triangle.h"
    >
    > int Example(void) {
    > IShape_t MyShape;
    >
    > int rStatus = Triangle_Create(&MyShape, /* [triangle params] */);
    > if (! rStatus) {
    >
    > rStatus = IShape_Draw(&MyShape);
    > if (rStatus) {
    >
    > rStatus = IObject_Status(&MyShape);
    > }
    >
    > rStatus = IObject_Destroy(&MyShape);
    > }
    >
    > return rStatus;}
    >
    > __________________________
    >
    > I was wondering if you have come across any superior methods for very basic
    > OOP in C?
    >
    > Any thoughts? Is this method total crap?
    >
    > ;^)
    >
    > Thanks.


    The following article also covers OO programming in C:
    http://www.eventhelix.com/RealtimeMantra/basics/object_oriented_programming_in_c.htm

    --
    EventStudio 4.0 - http://www.EventHelix.com/EventStudio
    Sequence Diagram based System Modeling Tool
    EventHelix.com, Jun 22, 2007
    #5
  6. "Chris Thomasson" <> wrote in message
    news:...
    > I was wondering if you have come across any superior methods for very
    > basic OOP in C?
    >


    typedef struct object
    {
    void *ptr;
    void *(*query)(struct object *obj, char *interface);
    void (*kill)(struct object *obj)
    } OBJECT;

    Every object you query for an interface. An example would be

    typedef struct
    {
    double (*length)(OBJECT *obj);
    int (*getpos)(OBJECT *obj, double t, double *x, double *y);
    } LINE;

    So we are passed a line

    void drawline(OBJECT *obj)
    {
    LINE *line;
    int len;
    int i;

    line = obj->query(obj, "line");
    if(!line)
    fprintf(stderr, "Must be passed a line\n"):
    len = (int) line->length(obj) + 1;
    for(i=0;i<len;i++)
    {
    line->getpos(obj, ((double)i)/len, &x, &y);
    drawpixel(x, y);
    }
    }

    However it really is a lot of trouble. The syntactical support isn't really
    there, so code quickly becomes a complete mess.

    --
    Free games and programming goodies.
    http://www.personal.leeds.ac.uk/~bgy1mm
    Malcolm McLean, Jun 22, 2007
    #6
  7. Barry Schwarz, Jun 22, 2007
    #7
  8. Chris Thomasson

    Richard Bos Guest

    Barry Schwarz <> wrote:

    > On Thu, 21 Jun 2007 19:52:19 -0700, "EventSpam.com"
    > <> wrote:
    >
    > >The following article also covers OO programming in C:
    > >http://www.eventspam.com/spam.htm

    >
    > Did you really need to quote 130+ lines just to provide a reference.


    No; but did you really need to quote a known spammer without munging his
    links?

    Richard
    Richard Bos, Jun 22, 2007
    #8
  9. On Fri, 22 Jun 2007 10:39:10 GMT, (Richard
    Bos) wrote:


    >
    >No; but did you really need to quote a known spammer without munging his
    >links?
    >

    He's not one of the spammers I recognized and the link actually
    contained reasonable C code.


    Remove del for email
    Barry Schwarz, Jun 22, 2007
    #9
  10. "Malcolm McLean" <> wrote in message
    news:...
    >
    > "Chris Thomasson" <> wrote in message
    > news:...
    >> I was wondering if you have come across any superior methods for very
    >> basic OOP in C?

    [...]
    > However it really is a lot of trouble. The syntactical support isn't
    > really there, so code quickly becomes a complete mess.


    Yeah, that seems to attempt to support more OOP techniques than the
    "minimalist" method posted, which only provides an abstract interface
    technique.
    Chris Thomasson, Jun 24, 2007
    #10
  11. Chris Thomasson wrote:
    > "Malcolm McLean" <> wrote in message
    > news:...
    >>
    >> "Chris Thomasson" <> wrote in message
    >> news:...
    >>> I was wondering if you have come across any superior methods for very
    >>> basic OOP in C?

    > [...]
    >> However it really is a lot of trouble. The syntactical support isn't
    >> really there, so code quickly becomes a complete mess.

    >
    > Yeah, that seems to attempt to support more OOP techniques than the
    > "minimalist" method posted, which only provides an abstract interface
    > technique.


    You are right, the syntactical support isn't really there, but it is
    quite possible to do full OOP in C with virtual functions and
    everything, and it isn't that hard to do really.
    It is even possible to do it better than in C++ with respect to using an
    object oriented plugin system, something not easily done in C++, at
    least not if you are *not* interested in recompiling every plugin at any
    change in some of the base classes. I do not know about C# or other
    languages - it might be better solved there but C is somewhat easier
    because everything becomes visible and that makes it easier to see the
    limitations and understand what happens. (I have done two
    implementations of plugin based object oriented systems, one in C++ and
    later one in C, the one in C actually meets the specifications better
    even if it is more lines of code to do the work).
    Johan Bengtsson, Jun 24, 2007
    #11
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Raymond Arthur St. Marie II of III

    very Very VERY dumb Question About The new Set( ) 's

    Raymond Arthur St. Marie II of III, Jul 23, 2003, in forum: Python
    Replies:
    4
    Views:
    452
    Raymond Hettinger
    Jul 27, 2003
  2. shanx__=|;-

    very very very long integer

    shanx__=|;-, Oct 16, 2004, in forum: C Programming
    Replies:
    19
    Views:
    1,594
    Merrill & Michele
    Oct 19, 2004
  3. Abhishek Jha

    very very very long integer

    Abhishek Jha, Oct 16, 2004, in forum: C Programming
    Replies:
    4
    Views:
    409
    jacob navia
    Oct 17, 2004
  4. Peter

    Very very very basic question

    Peter, Feb 8, 2005, in forum: C Programming
    Replies:
    14
    Views:
    500
    Dave Thompson
    Feb 14, 2005
  5. olivier.melcher

    Help running a very very very simple code

    olivier.melcher, May 12, 2008, in forum: Java
    Replies:
    8
    Views:
    2,247
Loading...

Share This Page