??? 06/19/07 16:04 Modified: 06/19/07 16:19 Read: times |
#141025 - Object Oriented Programming in C |
Oliver said:
Once you think OO, even your 8051 C code ends up with an OO design influence. Jan said:
This IS interesting. Can you please elaborate on this? Maybe a short example? (and maybe moving to a new thread, if you agree?) I don't consider myself an "OO thinker" by any stretch, but I do wind up writing some OOP-like C once in a while when it seems to make sense. As an example, the last bit of firmware that I did had to talk to seven UARTs. Two of them were the on-board UARTs on a C8051F120, and the other five were five channels of an external octal UART chip. Being somewhat naturally lazy, and also worried about using up all my code space, I didn't want to duplicate a bunch of code seven times. So I wound up making a UART "class" and seven UART "objects" in C. Here are some snippets that show how I did it. The UART "class definition" typedef struct { char rxIn; /* Next empty spot in rxBuff[] */ char rxOut; /* Oldest byte in rxBuff[] */ char *rxBuff; /* Pointer to actual buffer */ char buffSize; /* Buffer size */ } CUartInfo;Instantiation of seven instances of the class char trboBuff[TRBO_BUFF_SIZE]; char lasrBuff[LASR_BUFF_SIZE]; char xmotBuff[XMOT_BUFF_SIZE]; char ymotBuff[YMOT_BUFF_SIZE]; char zmotBuff[ZMOT_BUFF_SIZE]; char hostBuff[HOST_BUFF_SIZE]; char dbugBuff[DBUG_BUFF_SIZE]; CUartInfo uarts[] = { /* Array of UART info structures */ { 0, 0, trboBuff, TRBO_BUFF_SIZE }, { 0, 0, lasrBuff, LASR_BUFF_SIZE }, { 0, 0, xmotBuff, XMOT_BUFF_SIZE }, { 0, 0, ymotBuff, YMOT_BUFF_SIZE }, { 0, 0, zmotBuff, ZMOT_BUFF_SIZE }, { 0, 0, hostBuff, HOST_BUFF_SIZE }, { 0, 0, dbugBuff, DBUG_BUFF_SIZE } };A couple of methods /* //////////////////////////////////////////////////////////////////////////// CharAvail() GetChar() /////////////////////////////////////////////////////////////////////////////// DESCRIPTION: CharAvail() indicates whether or not unread data has accumulated in the input buffer. GetChar() waits for such data and returns the oldest character in the buffer. REVISIONS: 27 Dec 06 - RAC - Adapted from the old kbhit() and getch() functions //////////////////////////////////////////////////////////////////////////// */ char CharAvail(char ID) { /* The buffer contains data */ return uarts[ID].rxIn != /* if the in and out */ uarts[ID].rxOut; /* indexes are different */ } /* End CharAvail() */ /* ///////////////////////////////////////////////////////////////////////// */ char GetChar(char ID) { char rv; /* Put return character here */ while (!CharAvail(ID)) ; /* Wait for a character */ rv = uarts[ID].rxBuff[uarts[ID].rxOut++]; /* Grab byte from rx buffer */ if (uarts[ID].rxOut == uarts[ID].buffSize) { /* Just reached buffer end */ uarts[ID].rxOut = 0; /* Wrap to the beginning */ } /* End 'reached buffer end' */ return rv; /* The answer */ } /* End getch() */With this setup, a typical method call looks like GetChar(PUMP_UART), rather than pumpUart.GetChar() like you might see in a language with direct OOP support. A variation on the theme would be to rewrite the methods to accept pointers to the CUartInfo structures instead of indexes into the uarts[] array. That might be a little more efficient, but it would mean everybody and his brother would have pointers to the elements of the uarts[] array, when in fact that information should be accessible only to the methods of the class. There are probably a million ways to do something similar. I would really be interested if Oliver would post what he did, to see how his approach compares to mine. -- Russ |
Topic | Author | Date |
Object Oriented Programming in C | 01/01/70 00:00 | |
Make it ugly. :) | 01/01/70 00:00 | |
Ugly and scary!!! | 01/01/70 00:00 | |
Logical approach | 01/01/70 00:00 | |
Wasn\\\'t Natural For Me | 01/01/70 00:00 | |
Nice post Russ. | 01/01/70 00:00 | |
Agree 100% | 01/01/70 00:00 | |
OOP in C | 01/01/70 00:00 | |
more OO in C | 01/01/70 00:00 | |
All good hints, for sure | 01/01/70 00:00 |