Passing struct using BFM_CORE_PAR2 [SOLVED]

On 27/01/2015 at 15:08, xxxxxxxx wrote:

User Information:
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) :

struct PolyData
	Vector p1;
	Vector p2;
	Vector p3;
	Vector p4;
	Int32 polyIndex;
PolyData polys;
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).

Best wishes,

On 29/01/2015 at 00:27, xxxxxxxx wrote:

Thank you.
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.

Best wishes,

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.

Best wishes,