Products > Programming

array of pointers to different types C

(1/6) > >>

Simon:
So in my efforts to receive a CAN bus message in a way that does not have me using "if" statements to check the message ID or filter element number in order to decide what to do with it I am trying to use an array of pointers. I find pointers a little confusing but only by using them do I get more versed in their use.

So far it is a right mess of errors, and being pointers even successful compilation is no guarantee.

The CAN message filter elements are all stored in consecutive order in RAM (Bosch MCAN controller), the buffer that the message goes into will reference the filter element number. This is very useful as it means that I can represent each ID with numbers from 0-127 rather than having to use the 11 or 29 bit ID. So this makes it easier to have an array of the data that is in a small array of up to 128 rather than 2048-536 million.

Now the fun bit of course is that the data in each array element will be different. So I thought it made sense to set up an array of pointers to each variable (structures) and use memcpy from the buffer of received data to the element of the array that is indexed by the filter element number (0-127).

Naturally not so easy.

So how do I do this? or should I have a union between an array of a generic structure type and the specific structure types that are used in each message ID also known by it's filter element number.

onsokumaru:
I think using a union is probably a good idea. Feels like you're overcomplicating yourself, but I kinda get your point on this.
If you have defined structures for each type of message, then just declare an union type with all of them:
union AllMessageData {
    struct MessageDataA msgA;
    struct MessageDataB msgB;
    // Add other message types here
};
Then you need a mechanism to do the adequate typecast when you want to access those structs in the array. Again, to avoid the switch case or if chain, I can't see how. Looks like you are looking for object oriented programming features in this case, like having a method with the same name in different classes, or even using c++ templates (if you though pointers were hard enough)

magic:
Not entirely sure what's going on here.

Could you provide concrete examples of the types, variables or arrays that already exist or need to exist?
What specific types or variables would you like to add and for what exact purpose?

Storing multiple different "things" in some sort of universal "container" is possible and not too hard, what's hard is taking a random item out of there and knowing what it is and what to do with it.

C++ templates, as the name suggests, are a great way to produce a thousand copies of the same code specialized for different types, but they don't help one code to deal with a thousand types at the same time.

Simon:
No I am not trying to put different data into the same container.

The data arrives in a RAM buffer, so this RAM buffer is of a fixed setup in terms of each elements contents. Each different message will contain unique variables, these can be represented as a structure for each, the structures may be different, they may be the same. The RAM buffer contains the index number of the message ID filter element, so from one small number that will at most be 127 I can identify each message.

What I am trying to do is create an array of pointers to each variable:

void *can_0_rx_variable_index[number of ID's]  ;

So I need to put the address of the variables into each element, this works so far:


--- Code: ---void can_0_std_filter_setup(uint16_t id , uint8_t filter_element_n , void * variable )
{
can_0_rx_variable_index[filter_element_n] = variable ;

// see MTTCAN 2.4.5
can_0_rx_std_filter[filter_element_n].reg = 0x1 << 30 // SFT Standard filter type: 0 = range, 1 = dual filter, 2 = filter + mask, 3 = disabled
| 0x1 << 27 // SFEC Standard Filter Element Configuration: Store in Rx FIFO 0 if filter matches
| id << 16  // Primary filter ID
| 0x0 << 15 // SSYNC: Standard Sync Message: generates the timestamp
| id << 0 ; // Secondary Filter ID: for a single ID use the same as for ID 1 with SFT set to 1
}

--- End code ---

This will be given the address of the variable: &variable when called to set up a filter and allocate the index that points to the variables that the messages in that slot correspond to. The "variable" will be the structures.

What I am struggling with is how to use memcpy() to take the data from the buffer and direct in into each address indexed structure.

screwbreaker:
Maybe I'm trying to do something very similar.
Tell me if I understood correctly:

You want an array of structures.
The structure is passed to your function as a void* pointer.
Each structure is different and you want to know with wich type if structure you are dealing with.
To know thet you want to check a specific variable inside the structure itself: "can_0_rx_std_filter[filter_element_n].reg" this one fo be clear.

But you have problems with the access to the variable because you are trying to access it from a generic pointer. Not the correct structure type.

Is this is right. You are in my same situation.
What I'm trying to do at the moment is to use a generic structure type. Which have only one element, the one I use as ID.
And then based on this ID use this structure as the correct type.
something like:

generic_struct *temp = (*generic_struct)variable; //variable is a void*

If (temp->reg == 1) { (struct1*)variable->var = float }
If (temp->reg == 2) { (struct2*)variable->string = "string" }

My problem is. I don't know if the element of an array are consecutive in memory. So, I don't know if I can thrust the result of an access to the element ID.

Navigation

[0] Message Index

[#] Next page

There was an error while thanking
Thanking...
Go to full version
Powered by SMFPacks Advanced Attachments Uploader Mod