[Kde-bindings] [Qyoto] crash when using QList returned by QMimeData.Urls

David Lechner david at lechnology.com
Wed Feb 20 21:10:41 UTC 2013


On 2/19/2013 9:43 PM, David Lechner wrote:
> So now, the question is where do I need to tell the native code to not
> destroy my QUrl object?

I have made some progress. I have found that marshall_ValueListItem() is 
deleting the QList object.

 > 			if (m->type().isStack()) {
 >				delete valuelist;
 >			}

which in turn deletes all of the items in the list. So, my solution is 
to copy each item in the list when we are marshaling here.

I am using the new keyword to keep this copy from being destroyed. I 
assume that C# will call delete on the native object when the C# object 
is GCed.

I have attached the patch that fixes this (in combination with the other 
patch I already posted)

-------------- next part --------------
commit 74cc36759937eb8d9a9762f9c14136bbb5f542b1
Author: David Lechner <david at lechnology.com>
Date:   Wed Feb 20 14:57:58 2013 -0600

    make void marshall_ValueListItem(Marshall *m) use copies of list items
    instead of the list items themselves so that the items are not destroyed
    when the list is destroyed

diff --git a/assemblies/qyoto-qtcore/native/marshall_macros.h b/assemblies/qyoto-qtcore/native/marshall_macros.h
index ba6b932..abf7c6a 100644
--- a/assemblies/qyoto-qtcore/native/marshall_macros.h
+++ b/assemblies/qyoto-qtcore/native/marshall_macros.h
@@ -104,6 +104,14 @@ void marshall_ItemList(Marshall *m) {
 #define DEF_LIST_MARSHALLER(ListIdent,ItemList,Item) namespace { char ListIdent##STR[] = #Item; }  \
         Marshall::HandlerFn marshall_##ListIdent = marshall_ItemList<Item,ItemList,ListIdent##STR>;
 
+
+
+// A ValueListItem means that the Item in ItemList uses implicit sharing, i.e. the class inherits
+// QSharedData. So, when marshalling ToObject, we will create a copy of each item in the list and pass
+// the copy back to C# rather than the object itself.
+//
+// See http://doc.qt.digia.com/stable/implicit-sharing.html for more info on implicit sharing.
+
 template <class Item, class ItemList, const char *ItemSTR >
 void marshall_ValueListItem(Marshall *m) {
 	switch(m->action()) {
@@ -157,13 +165,9 @@ void marshall_ValueListItem(Marshall *m) {
 			void * al = (*ConstructList)(className);
 
 			for (int i=0; i < valuelist->size() ; ++i) {
-				void *p = (void *) &(valuelist->at(i));
-				void * obj = (*GetInstance)(p, true);
-
-				if (obj == 0) {
-					smokeqyoto_object * o = alloc_smokeqyoto_object(false, ix.smoke, ix.index, p);
-					obj = (*CreateInstance)(qyoto_resolve_classname(o), o);
-				}
+				void *p = (void *) new Item(valuelist->at(i));
+				smokeqyoto_object *o = alloc_smokeqyoto_object(false, ix.smoke, ix.index, p);
+				void *obj = (*CreateInstance)(qyoto_resolve_classname(o), o);
 
 				(*AddIntPtrToList)(al, obj);
 				(*FreeGCHandle)(obj);


More information about the Kde-bindings mailing list