I've started working with CAN some months ago (with the microchip ECAN module)
What i suggest you do is put a series of abstraction layers.
Highest, optional, you have the action you want to do (ie: get_rpm() which will send and receive messages in the obd2 format)
Then, a second architecture-independend layer where you generate the message in a friendly format (i have a structure type called can_t with all the data in a user friendly format (id, id format bit (byte), rtr bit, dlc, data bytes, padding bytes to make the structure aligned to the memory bus width) and then the processor-specific interface, that rearrange the bytes in the way the can module wants and vice/versa.
On a dspic there is not much overhead and it's a great way to preserve sanity