Я узнал, что ADT является важной концепцией, и я изучаю эту технологию.
Вот проблема, с которой я не знаю, как справиться.
Payload_Manager.h
typedef struct __attribute__((__packed__))
{
u32 Addr;
u16 Cmd;
u16 Len;
u8 Data[0];
}ATEIS_Payload_s; //payload
Payload_Manager.c
#include "Payload_Manager.h"
void* Payload_Manager_New(int size)
{
return (ATEIS_Payload_s*)malloc(size);
}
void* Payload_Manager_Ctor(void* _this, u32 ip, u16 cmdID, u16 dataLen, char* rxBuf)
{
ATEIS_Payload_s* this = (ATEIS_Payload_s*)_this;
this->Addr = ip;
this->Cmd = cmdID;
this->Len = dataLen;
memcpy(this->Data, rxBuf, dataLen);
return this;
}
void* Payload_Manager_Dtor(void** _this)
{
free(*_this);
*_this = NULL;
return *_this;
}
DNM_Manager.h
void* DNMManager_Ctor(void* _this,
void* name,
u32 ip,
u32 sn,
u32 subMask);
DNM_Manager.c
typedef struct
{
u32 Addr;
u32 SerialNo;
u32 SubnetMask;
char Name[NAME_SIZE];
}DNM;
static DNM DNMSet[SET_SIZE];
static DNM DNMTemp;
void* DNMManager_Ctor(void* _this,
void* name,
u32 ip,
u32 sn,
u32 subMask)
{
DNM* this = (DNM*)_this;
memcpy(this->Name, name, NAME_SIZE);
this->Addr = ip;
this->SerialNo = sn;
this->SubnetMask = subMask;
return this;
}
CmdHndlr.c
#include "Payload_Manager.h"
#include "DNM_Manager.h"
int main(void){
ATEIS_Payload_s* pl_p = NULL;
void* DNM_temp = NULL;
pl_p = OSTaskQPend(0, OS_OPT_PEND_BLOCKING, &msgSize, &ts, &err); //wait for a message
/*This works properly*/
DNM_temp = DNMManager_Ctor(DNM_temp,
&pl_p->Data[NAME],
pl_p->Addr,
*(u32*)&pl_p->Data[SN],
*(u32*)&pl_p->Data[SUBMASK]);
/*following code is omitted*/
}
Теперь я не хочу, чтобы другие файлы знали тип "ATEIS_Payload_s", за исключением функций в Payload_Manager.c. Потому что только функции в Payload_Manager.c имеют дело с типом «полезная нагрузка».
Другими словами, я хочу изменить код в CmdHndlr.c на:
//#include "Payload_Manager.h" /*no need anymore*/
#include "DNM_Manager.h"
int main(void){
void* pl_p = NULL; //programmer no need to know what type pl_p is
void* DNM_temp = NULL;
pl_p = OSTaskQPend(0, OS_OPT_PEND_BLOCKING, &msgSize, &ts, &err); //wait for a message
DNM_temp = DNMManager_Ctor(DNM_temp, pl_p); //DNM_Manager_Ctor will deal with it.
/*following code is omitted*/
}
Здесь стоит отметить: функция «DNM_Manager_Ctor» обрабатывает типы «DNM» и «ATEIS_Payload_s» одновременно.
Это достигается тем, что DNM_Manager_Ctor знает оба типа "DNM" и "ATEIS_Payload_s". Это означает, что изменение DNM_Manager.c на:
typedef struct
{
u32 Addr;
u32 SerialNo;
u32 SubnetMask;
char Name[NAME_SIZE];
}DNM;
typedef struct __attribute__((__packed__)) //oops, already declared in somewhere else. Is this valid?
{
u32 Addr;
u16 Cmd;
u16 Len;
u8 Data[0];
}ATEIS_Payload_s; //payload
void* DNMManager_Ctor(void* _this,
void* _dest)
{
DNM* this = (DNM*)_this;
ATEIS_Payload_s* dest = (ATEIS_Payload_s*)_dest;
/*following is omitted*/
return result;
}
Я не знаю, допустим ли этот способ. Но этот способ явно уменьшит модульность, даже если он действителен.
Есть ли лучший способ решить это?
редактирование:
Я новичок в объектно-ориентированном. Я пытаюсь реализовать эту концепцию в C, хотя это очень грубо. Кроме того, весьма вероятно, что я неправильно использовал эту концепцию в этой программе.