+//---------------------------------------------------------------------------
+
+void wxPyClientData_dtor(wxPyClientData* self) {
+ wxPyBeginBlockThreads();
+ Py_DECREF(self->m_obj);
+ wxPyEndBlockThreads();
+}
+
+void wxPyUserData_dtor(wxPyUserData* self) {
+ wxPyBeginBlockThreads();
+ Py_DECREF(self->m_obj);
+ wxPyEndBlockThreads();
+}
+
+
+// This is called when an OOR controled object is being destroyed. Although
+// the C++ object is going away there is no way to force the Python object
+// (and all references to it) to die too. This causes problems (crashes) in
+// wxPython when a python shadow object attempts to call a C++ method using
+// the now bogus pointer... So to try and prevent this we'll do a little black
+// magic and change the class of the python instance to a class that will
+// raise an exception for any attempt to call methods with it. See
+// _wxPyDeadObject in _extras.py for the implementation of this class.
+void wxPyOORClientData_dtor(wxPyOORClientData* self) {
+
+ static PyObject* deadObjectClass = NULL;
+
+ wxPyBeginBlockThreads();
+ if (deadObjectClass == NULL) {
+ deadObjectClass = PyDict_GetItemString(wxPython_dict, "_wxPyDeadObject");
+ wxASSERT_MSG(deadObjectClass != NULL, wxT("Can't get _wxPyDeadObject class!"));
+ Py_INCREF(deadObjectClass);
+ }
+
+ // Clear the instance's dictionary, put the name of the old class into the
+ // instance, and then reset the class to be the dead class.
+ if (self->m_obj->ob_refcnt > 1) { // but only if there is more than one reference
+ wxASSERT_MSG(PyInstance_Check(self->m_obj), wxT("m_obj not an instance!?!?!"));
+ PyInstanceObject* inst = (PyInstanceObject*)self->m_obj;
+ PyDict_Clear(inst->in_dict);
+ PyDict_SetItemString(inst->in_dict, "_name", inst->in_class->cl_name);
+ inst->in_class = (PyClassObject*)deadObjectClass;
+ Py_INCREF(deadObjectClass);
+ }
+ wxPyEndBlockThreads();
+}