On 27/01/2015 at 15:08, xxxxxxxx wrote:
Cinema 4D Version: R15
Platform: Windows ;
Language(s) : C++ ;
I like to send a struct with information using SpecialEventAdd and BFM_CORE_PAR2.
But I can not get it to work. A single value is ok, but a struct is not working
Here the sending part (the compiler is not complaining) :
polys.polyIndex = polygonid;
polys.p1 = Vector(1,0,0);
polys.p2 = Vector(2,0,0);
polys.p3 = Vector(3,0,0);
polys.p4 = Vector(4,0,0);
SpecialEventAdd(OCTREE_ID, OCTREE_ID, (UInt) &polys );
If I use SpecialEventAdd(OCTREE_ID, OCTREE_ID, (PolyData * ) &polys ) the compiler start to complain.
The receiving part in CoreMessage:
PolyData* my_data = (PolyData * ) msg.GetVoid( BFM_CORE_PAR2 );
GePrint("Polygon id: " + String::IntToString(my_data->polyIndex));
For the compiler it is ok, but I do not receive the expected values. Mostly rubbish.
If I use (UInt) msg.GetVoid( BFM_CORE_PAR2 ) the compiler starts to complain.
So, I guess something goes wrong because when sending I use (UInt) and when receiving I use (PolyData * ).
How to solve this issue?
On 28/01/2015 at 06:43, xxxxxxxx wrote:
SpecialEventAdd adds a custom event to the event queue. This means that SpecialEventAdd will not immediately call any other function but will store the message and it's data. In this case the data are two Uint32 numbers (that may be abused as pointers).
So SpecialEventAdd won't store or copy the object the pointer is pointing to. You have to make sure that the stored pointer is still valid when you read it. To make sure that the pointer is still valid you should not use the address of an object allocated on the stack. You should allocate it dynamically (and of course free it later).
On 29/01/2015 at 00:27, xxxxxxxx wrote:
Could you give us an example how to do that (allocate and use the pointer in the call)?
On 29/01/2015 at 01:07, xxxxxxxx wrote:
there is nothing special about allocating memory dynamically for that case. Just allocate a new object (preferable with Cinema's memory functions like NewObj()) and cast that pointer to an Uint.
PolyData* data = NewObj(PolyData);
// check pointer and fill your object
SpecialEventAdd(123456789, 0, (UInt) data);
Just be sure to free that memory at some point to avoid a memory leak.
On 29/01/2015 at 01:57, xxxxxxxx wrote:
Great, a very logical solution, thanks.
I do need to think about the difference between:
- PolyData data;
data.p1 = Vector(1,0,0)
SpecialEventAdd(OCTREE_ID, OCTREE_ID, (UInt) &data);
- PolyData* data = NewObj(PolyData);
data->p1 = Vector(1,0,0);
SpecialEventAdd(OCTREE_ID, OCTREE_ID, (UInt) data);
And yes, the issue of freeing the memory.
I guess I can not use AutoAlloc?
Is it an option to create the data (PolyData* data = NewObj(PolyData);)only once and re-use it?
Or free it before creating it again?
So: 1) if already there -> free
2) Create data.
On 29/01/2015 at 02:28, xxxxxxxx wrote:
AutoAlloc can be used to handle objects that implement Alloc() and Free() functions and will free the object's memory at the end of the variable scope (take a look at the file ge_autoptr.h in frameworks\cinema.framework\source).
Of course it is possible to free the data associated with a pointer and then allocate new data.
I heavily suggest to do some research on the topics pointers, dynamic memory allocation, stack, heap and variable scopes. For questions no longer related to this thread's original topic please open a new thread. Thanks.