To be more clear about the purpose of Dart_Handle:
Because Dart has a garbage-collected heap of objects, and the garbage collector can move objects around, you can't keep pointers to objects in C++ code that could be interrupted by garbage collections. So you allocate Dart_Handles, which are a bunch of places THAT THE GC KNOWS ABOUT holding pointers to objects. That way, when the GC moves an object, it updates the pointer in that place (that Dart_Handle). So your C++ code, but more importantly the Dart embedding API calls that your code makes, can grab the object pointer out of that handle and do stuff with it (but reloading the pointer from the handle any time a GC could have happened).
The Dart_Handles that the GC knows about can be created in various ways: in Zones, as permanent handles, etc. You can't just make one using 'new'. The memory management of the handles has to be done more carefully and explicitly, and they aren't GCd, since their reason for existing is to be a C++ pointer that isn't touched by the GC, that points to a Dart object pointer.