打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Object Oriented Programming in C
Embedded software development is slowly moving towards object orientedanalysis, designand programming. The introduction of object oriented technologies in somesystems has not happened due to lack of C++ support on some platforms.
This article focuses on platforms where C++ compilers are not available. Thedevelopers working on these platforms should still be able to use objectoriented analysis and design. When it comes to final code development they canuse C.
The following sections cover an example of C++ code and its implementation inC.
C++ Source Code: C++ source files implementing TerminalManager and Terminal classes.
C Source Code: TerminalManager and Terminal implemented in C for a platform that does not support C++.
Terminal Manager and Terminal C++ header and source files are shownbelow:
Terminal Manager
TerminalManager.hpp
// TerminalManager header file. We will be using this class
// as an example for Object Oriented Programming in C.
#include "Terminal.hpp"
class TerminalManager
{
private:
enum {MAX_TERMINALS=500};
Terminal terminals[MAX_TERMINALS];
Terminal *FindTerminal(int terminalId);
public:
TerminalManager();
~TerminalManager();
void HandleMessage(Msg* pMsg);
};
TerminalManager.cpp
// TerminalManager source file. We will be using this class
// as an example for Object Oriented Programming in C.
#include <stdio.h>
#include "TerminalManager.hpp"
#include "Msg.hpp"
TerminalManager::TerminalManager()
{
//...
}
TerminalManager::~TerminalManager()
{
}
void TerminalManager::HandleMessage(Msg* pMsg)
{
int status, status1;
int terminalId = pMsg->GetTerminalId();
Terminal *pTerm = FindTerminal(terminalId);
Terminal *pOtherTerm = NULL;
if (pTerm != NULL)
{
switch (pMsg->GetType())
{
case CREATE_TERMINAL:
pTerm->Activate((const TerminalCreateMsg *)pMsg);
break;
case DELETE_TERMINAL:
pTerm->Deactivate((const TerminalDeleteMsg *) pMsg);
break;
case RUN_DIAGNOSTICS:
status = pTerm->HandleRunDiagnostics((const RunDiagnosticsMsg *) pMsg);
break;
case PERFORM_SWITCHOVER:
pOtherTerm = FindTerminal(pMsg->GetOtherTerminalId());
status = pTerm->HandleOutOfService();
status1 = pOtherTerm->HandleInService();
break;
}
}
delete pMsg;
}
Terminal *TerminalManager::FindTerminal(int terminalId)
{
if (terminalId < MAX_TERMINALS)
{
return (&terminals[terminalId]);
}
else
{
return NULL;
}
}
Terminal
Terminal.hpp
// Terminal class header file.
// Forward declaration for messages
class TerminalCreateMsg;
class TerminalDeleteMsg;
class RunDiagnosticsMsg;
class Msg;
// Terminal class
class Terminal
{
enum { UNKNOWN = 0 };
enum {OUT_OF_SERVICE=1, INSERVICE=2};
//...
int terminalId;
int terminalType;
int terminalStatus;
void SendMessage(Msg *pMsg);
public:
void Activate(const TerminalCreateMsg *pMsg);
void Deactivate(const TerminalDeleteMsg *pMsg);
int HandleRunDiagnostics(const RunDiagnosticsMsg *pMsg);
int HandleOutOfService();
int HandleInService();
Terminal();
~Terminal();
};
Terminal.cpp
// Terminal class source file.
#include "Terminal.hpp"
#include "Msg.hpp"
void Terminal::SendMessage(Msg *pMsg)
{
//...
}
Terminal::Terminal()
{
terminalId = UNKNOWN;
terminalType = UNKNOWN;
terminalStatus = UNKNOWN;
}
Terminal::~Terminal()
{
//...
}
int Terminal::HandleRunDiagnostics(const RunDiagnosticsMsg *pMsg)
{
int status = 1;
//...
return status;
}
int Terminal::HandleOutOfService()
{
int status = 1;
terminalStatus = OUT_OF_SERVICE;
//...
return status;
}
int Terminal::HandleInService()
{
int status = 1;
terminalStatus = INSERVICE;
//...
return status;
}
void Terminal::Activate(const TerminalCreateMsg *pMsg)
{
terminalId = pMsg->GetTerminalId();
terminalType = pMsg->GetTerminalType();
terminalStatus = pMsg->GetTerminalStatus();
//...
TerminalCreateAck *pAck = new TerminalCreateAck(terminalId, terminalStatus);
SendMessage(pAck);
}
void Terminal::Deactivate(const TerminalDeleteMsg *pMsg)
{
//...
terminalId = UNKNOWN;
terminalType = UNKNOWN;
terminalStatus = UNKNOWN;
//...
}
Msg.hpp
// Messages used by the Terminal and TerminalManager classes.
enum MsgType
{
CREATE_TERMINAL,
DELETE_TERMINAL,
RUN_DIAGNOSTICS,
PERFORM_SWITCHOVER
};
class Msg
{
//...
int msgType;
int terminalType;
int terminalId;
int otherTerminalId;
int terminalStatus;
public:
MsgType GetType() const;
int GetTerminalId() const;
int GetOtherTerminalId() const;
int GetTerminalType() const;
};
// Message used to create a terminal
class TerminalCreateMsg : public Msg
{
public:
int GetTerminalStatus() const;
};
// Acknowledgement to Terminal Create message.
class TerminalCreateAck : public Msg
{
public:
TerminalCreateAck(int terminalId, int terminalStatus);
};
// Terminal Delete message
class TerminalDeleteMsg : public Msg
{
};
Terminal Manager and Terminal C header and source files are shown below. Theimportant points to note are:
Data members of a class map to C structures
Methods of a class map to C functions with the "data member" structure pointer as the first parameter.
TerminalManager
TerminalManager.h
/*
TerminalManager header file. We will be using this class
as an example for Object Oriented Programming in C.
*/
#include "Terminal.h"
#define MAX_TERMINALS 500
/* Structure contains all data used by the Terminal Manager. */
typedef struct
{
Terminal terminals[MAX_TERMINALS];
} TerminalManager;
/*
ANSI C Function prototypes of all functions that operate
on the TerminalManager structure.
*/
void TerminalManager_Construct(TerminalManager *pMgr);
void TerminalManager_Destroy(TerminalManager *pMgr);
void TerminalManager_HandleMessage(TerminalManager *pMgr, Msg* pMsg);
Terminal Manager.c
/*
TerminalManager source file. We will be using this class
as an example for Object Oriented Programming in C.
*/
#include <stdio.h>
#include "TerminalManager.h"
#include "Msg.h"
#include <stdlib.h>
Terminal *TerminalManager_FindTerminal(TerminalManager *pMgr, int terminalId)
{
if (terminalId < MAX_TERMINALS)
{
return (&(pMgr->terminals[terminalId]));
}
else
{
return NULL;
}
}
void TerminalManager_Construct(TerminalManager *pMgr)
{
int i;
/*
C will not call construction functions, so loop through all call the
construction functions for all terminals.
*/
for (i=0; i < MAX_TERMINALS; i++)
{
Terminal_Construct(&(pMgr->terminals[i]));
}
}
void TerminalManager_Destroy(TerminalManager *pMgr)
{
int i;
/*
C will not call destruction functions, so loop through all call the
destruction functions for all terminals.
*/
for (i=0; i < MAX_TERMINALS; i++)
{
Terminal_Destroy(&(pMgr->terminals[i]));
}
}
void TerminalManager_HandleMessage(TerminalManager *pMgr, Msg* pMsg)
{
int status, status1;
int terminalId = pMsg->terminalId;
Terminal *pTerm = TerminalManager_FindTerminal(pMgr, terminalId);
Terminal *pOtherTerm = NULL;
/*
Switch on the message type and invoke the Terminal's message handlers for
the terminal specified in the message. Here the terminal manager takes
care of indexing into the terminal structure and it passes the pointer
to the terminal handler functions. Due to this design, implementation
of the terminal handler functions just focus on handling the specified
terminal.
*/
if (pTerm != NULL)
{
switch (pMsg->msgType)
{
case CREATE_TERMINAL:
Terminal_Activate(pTerm, (const TerminalCreateMsg *)pMsg);
break;
case DELETE_TERMINAL:
Terminal_Deactivate(pTerm, (const TerminalDeleteMsg *) pMsg);
break;
case RUN_DIAGNOSTICS:
status = Terminal_HandleRunDiagnostics(pTerm, (const RunDiagnosticsMsg *) pMsg);
break;
case PERFORM_SWITCHOVER:
pOtherTerm = TerminalManager_FindTerminal(pMgr, pMsg->otherTerminalId);
status = Terminal_HandleOutOfService(pTerm);
status1 = Terminal_HandleInService(pOtherTerm);
break;
}
}
free(pMsg);
}
Terminal
Terminal.h
/* Terminal struct header file. */
#include "Msg.h"
#define UNKNOWN 0
#define OUT_OF_SERVICE 1
#define INSERVICE 2
/* Terminal struct */
typedef struct
{
/*...*/
int terminalId;
int terminalType;
int terminalStatus;
} Terminal;
/*
Prototypes for Terminal structure related functions. Helper
functions needed by these functions are marked static are not
included here.
*/
void Terminal_Activate(Terminal *pTerm, const TerminalCreateMsg *pMsg);
void Terminal_Deactivate(Terminal *pTerm, const TerminalDeleteMsg *pMsg);
int Terminal_HandleRunDiagnostics(Terminal *pTerm, const RunDiagnosticsMsg *pMsg);
int Terminal_HandleOutOfService(Terminal *pTerm);
int Terminal_HandleInService(Terminal *pTerm);
void Terminal_Construct(Terminal *pTerm);
void Terminal_Destroy(Terminal *pTerm);
Terminal.c
/* Terminal struct source file. */
#include "Terminal.h"
#include "Msg.h"
#include <stdlib.h>
/*
Terminal_SendMessage is not visible to outside the Terminal.c file.
This is equivalent to a private method in C++.
*/
static void Terminal_SendMessage(Terminal *pTerm, Msg *pMsg)
{
/*...*/
}
void Terminal_Construct(Terminal *pTerm)
{
pTerm->terminalId = UNKNOWN;
pTerm->terminalType = UNKNOWN;
pTerm->terminalStatus = UNKNOWN;
}
void Terminal_Destroy(Terminal *pTerm)
{
/*...*/
}
int Terminal_HandleRunDiagnostics(Terminal *pTerm, const RunDiagnosticsMsg *pMsg)
{
int status = 1;
/*...*/
return status;
}
int Terminal_HandleOutOfService(Terminal *pTerm)
{
int status = 1;
pTerm->terminalStatus = OUT_OF_SERVICE;
/*...*/
return status;
}
int Terminal_HandleInService(Terminal *pTerm)
{
int status = 1;
pTerm->terminalStatus = INSERVICE;
/*...*/
return status;
}
void Terminal_Activate(Terminal *pTerm, const TerminalCreateMsg *pMsg)
{
TerminalCreateAck *pAck;
pTerm->terminalId = pMsg->header.terminalId;
pTerm->terminalType = pMsg->header.terminalType;
pTerm->terminalStatus = pMsg->header.terminalStatus;
/*...*/
pAck = (TerminalCreateAck *)malloc(sizeof(TerminalCreateAck));
pAck->header.terminalId = pTerm->terminalId;
pAck->header.terminalStatus = pTerm->terminalStatus;
Terminal_SendMessage(pTerm, (Msg *)pAck);
}
void Terminal_Deactivate(Terminal *pTerm, const TerminalDeleteMsg *pMsg)
{
/*...*/
pTerm->terminalId = UNKNOWN;
pTerm->terminalType = UNKNOWN;
pTerm->terminalStatus = UNKNOWN;
/*...*/
}
Msg.h
/* Messages used by the Terminal and TerminalManager classes. */
#ifndef MSG_H
#define MSG_H
enum MsgType
{
CREATE_TERMINAL,
DELETE_TERMINAL,
RUN_DIAGNOSTICS,
PERFORM_SWITCHOVER
};
typedef struct
{
/*...*/
int msgType;
int terminalType;
int terminalId;
int otherTerminalId;
int terminalStatus;
} Msg;
/* Message used to create a terminal. */
typedef struct
{
Msg header;
}TerminalCreateMsg;
/* Acknowledgement to Terminal Create message. */
typedef struct
{
Msg header;
} TerminalCreateAck;
/* Terminal Delete message */
typedef struct
{
Msg header;
} TerminalDeleteMsg;
typedef struct
{
Msg header;
} RunDiagnosticsMsg;
#endif
Explore More
Compare C++ and the equivalent C code for class declarations and method invocation
Compare C++ and the equivalent C code for inheritance and virtual functions.
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
MFC-消息分派
C语言开发如何用130行代码写出超火微信小游戏(需要准备的图片素材作为变量)
数据驱动编程之表驱动法
MFC限制Edit控件只输入数字、小数点及失去焦点
ucgui_向按钮发送一个按键消息的程序追踪
MQL4/MQL5 函数变化对照表|MT5编程交流
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服