Do note. *NEVER* use void* to pass things in a C++ program as it destroys type information, very bad when using scripting languages...
You should just do what I did in my engine. I have a base class from which all game objects are inherited from, "Actor". I do things like this in my engine:
// Assuming base class is Actor, Doodad is subclassed from Actor, Box is subclassed from Doodad
// Actor and Doodad exist both in C++ and the script, Box is script only
ActorPtr aBox = Actor::Spawn("Box");
if(!aBox) return false;
aBox->setPosition(0.0,1.0,2.0);
ObjectPtr aBoxSelf = aBox.getSelf()
aBoxSelf.attr("someScriptMethod")(3, "hi");
Doodad aDoodadBox = Doodad::cast(aDoodadBox);
if(!aDoodadBox) throw SomeBigError();
aDoodadBox->DoodadFly(1.4);
assert(aBox==aDoodadBox && aBoxSelf==aDoodadBox.getSelf());
aBox.Destroy();
aDoodadBox.reset();
aBoxSelf.reset();
aBox.reset();
First I spawn an Actor of type "Box" (could exist in C++ or Python or wherever). I then check to make sure it actually spawned (could be a few cases why, abstract, can't fit, not allowed in the level, etc...).
I then set its 3d position like a pointer.
I then get the direct script interface object and put it in aBoxSelf. I then call a script only method that does not have a C++ signature (a function in the class that does not exist on Actor base since the pointer is an ActorPtr). I can pass whatever I want to it as well, could even return values (as an Object, which I can then extract whatever out of).
Since I spawned a box, and box inherits from Doodad (which inherits from Actor), and since Doodad is a C++ class, I then cast it using a convenient static method in Doodad (I have a single macro call which you put in any C++ subclass of Actor to auto make many helper static functions like that cast one), and make sure it is valid. I then call a method that exists only on the Doodad class and its subclasses, the method could even be overridden by the box subclass, even though it exists in script, through the DoodadPtr. I then call the Destroy method on the aBox ActorPtr which tells the in-game object to remove itself from the game, clean-up, calls the Destroyed method that they can subclass to do proper clean-up, resets all other ActorPtr's in the class (to prevent cyclic link so they will actually die correctly), and so on. The class itself, although basically turned off, still exists. Method's can be called on it and so on, although most will do nothing (no script functions are called when an instance is turned off unless then have a decorator on the function that specify they can be called after the instance is dead). So pointers are still valid, information can be gathered, etc... When the actual ActorPtr's (or derivatives) are .reset(), and all links in Python are deleted, then the class is free'd. To do the same functionality (call the same things and so on) inside the script, you would do something like this:
aBox = Spawn("Box")
# I could also pass the class itself if I have imported it like: aBox = Spawn(Box)
if not aBox: return false
aBox.setPosition(0.0,1.0,2.0)
aBox.someScriptMethod(3, "hi")
aBox.DoodadFly(1.4)
aBox.Destroy()
del aBox
And yes, if an Actor loses all links, it will be Destroy'd, then free'd, although the active level keeps a pointer to all game instances inside the level, if the level changes or dies or what-not, a LevelChange event is called on the instances that, by default, just call Destroy (but they could do other things, like stick around for the next level, as long as they remember to add themselves to it).
And yea, I'm not sure how "CollisionActor *act = (CollisionActor)actor;" would get past without generating a nice Warning at the least.

Does Squirrel have a JIT out of curiosity? I've been using psyco to JIT most python code (tremendous speed boosts I must say), but been looking quite a bit into PyPy recently, which fully compiles Python code to machine code. It is not 1.0 status yet, but I cannot wait...