Reputation: 101
I am trying to create a structure with nested functions, that passes the structure itself as an argument into the nested function for simplification of calling functions. The code will be run on a Pic 24f series mcu using the xc16 compiler. Also, I know the count function is redundant but I think it illustrates my point. For example:
Structure:
typedef struct
{
uchar Fifo[UART1_RX_MAX_BUFFER_SIZE];
uchar FifoIndex = 0;
uchar FifoCount = 0;
uchar FifoOverrunFlag = FALSE;
uchar (*CountPointer);
uchar (*PutPointer);
}Fifo;
Functions:
// Returns: The number of items in the Fifo
uchar FifoGetCount(Fifo *fifo)
{
return fifo->FifoCount;
}
// Summary: Adds data to the end of the Fifo
// Parameters:
// data: Data to be added to the end of the Fifo
// Returns: True (1) if the data was successfully added
// False (0) if the data was not successfully added
// as a result of the Fifo being full
uchar FifoPut(Fifo *fifo, uchar data)
{
if (fifo->FifoCount > FIFO_MAX_SIZE)
{
fifo->FifoOverrunFlag = TRUE;
return FALSE;
}
uint putIndex = fifo->FifoGetPutIndex();
fifo->Fifo[putIndex] = data;
fifo->FifoCount++;
return TRUE;
}
Main:
Fifo fifo1;
int main()
{
fifo1.CountPointer = FifoGetCount(fifo1);
fifo1.PutPointer = FifoPut(fifo1, uchar data);
// Intended Usage
uchar myCount = fifo1.FifoGetCount();
uchar myData = 1;
fifo1.FifoPut(myData);
}
Upvotes: 1
Views: 1155
Reputation: 754700
Note that uchar (*PutPointer);
is just a funny way of writing uchar *PutPointer;
. To create a function pointer, you'd have to write: uchar (*PutPointer)(…);
where the …
should be replaced by a specification of the types of the arguments — a prototype.
Since you have a function uchar FifoPut(Fifo *fifo, uchar data)
, it seems likely that you should be writing:
typedef struct Fifo Fifo;
struct Fifo
{
uchar Fifo[UART1_RX_MAX_BUFFER_SIZE];
uchar FifoIndex = 0;
uchar FifoCount = 0;
uchar FifoOverrunFlag = FALSE;
uchar (*CountPointer)(Fifo *fifo);
uchar (*PutPointer)(Fifo *fifo, uchar data);
};
And then, in main()
, you could write:
fifo1.CountPointer = FifoGetCount;
fifo1.PutPointer = FifoPut;
This assigns the function pointers FifoGetCount
and FifiPut
to the elements of the struct. The code you had assigned a uchar
value generated by calling the function once to a uchar *
. This should have been generating compiler warnings. If it was, you should have said so in your question. If it wasn't, you need turn on relevant compiler warnings, or get a better compiler.
You could then use the function as:
uchar myCount = fifo1.FifoGetCount(&fifo1);
uchar myData = 1;
fifo1.FifoPut(&fifo1, myData);
Note that you have to explicitly pass the address of the structure as the first argument to the functions; the C compiler is not going to do that for you by magic. If you want that done implicitly, the language you're looking for is called C++.
Upvotes: 1