diff options
author | Jan Jezabek <jezabek@poczta.onet.pl> | 2008-07-21 12:17:13 +0000 |
---|---|---|
committer | Jan Jezabek <jezabek@poczta.onet.pl> | 2008-07-21 12:17:13 +0000 |
commit | 1cb2f1e0e0266bcf427bd17988516f736cd8269b (patch) | |
tree | 0a9b64765fa06cb6bd13b29e8bec541d39402740 | |
parent | 375e76891b707aa150deab475abac428aaa16886 (diff) | |
download | swig-1cb2f1e0e0266bcf427bd17988516f736cd8269b.tar.gz |
Handle memory ownership. Underlying objects are now deleted when their owning proxies reach refCount 0, and proper destructors are called.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/gsoc2008-jezabek@10692 626c5289-ae23-0410-ae9c-e8d60b6d4f22
-rw-r--r-- | Lib/com/com.swg | 39 | ||||
-rw-r--r-- | Source/Modules/com.cxx | 11 |
2 files changed, 29 insertions, 21 deletions
diff --git a/Lib/com/com.swg b/Lib/com/com.swg index 451fac8e5..a134ac342 100644 --- a/Lib/com/com.swg +++ b/Lib/com/com.swg @@ -92,21 +92,21 @@ %typemap(out) void "" %typemap(out) SWIGTYPE * %{ - $result = (SWIGIUnknown *) SWIG_wrap$comclassname((void *) $1); + $result = (SWIGIUnknown *) SWIG_wrap$comclassname((void *) $1, $owner); %} %typemap(out) SWIGTYPE & %{ - $result = (SWIGIUnknown *) SWIG_wrap$comclassname((void *) $1); + $result = (SWIGIUnknown *) SWIG_wrap$comclassname((void *) $1, $owner); %} %typemap(out) SWIGTYPE #ifdef __cplusplus -%{ $result = (SWIGIUnknown *) SWIG_wrap$comclassname((void *) new $1_ltype((const $1_ltype &)$1)); %} +%{ $result = (SWIGIUnknown *) SWIG_wrap$comclassname((void *) new $1_ltype((const $1_ltype &)$1), $owner); %} #else { $&1_ltype $1ptr = ($&1_ltype) malloc(sizeof($1_ltype)); memmove($1ptr, &$1, sizeof($1_type)); - $result = (SWIGIUnknown *) SWIG_wrap$comclassname((void *) $1ptr); + $result = (SWIGIUnknown *) SWIG_wrap$comclassname((void *) $1ptr, $owner); } #endif @@ -128,11 +128,23 @@ typedef void (SWIGSTDCALL *SWIG_funcptr)(void); typedef struct { + SWIG_funcptr *vtable; + SWIG_funcptr newInstance; + LONG refCount; +} SWIGClassFactory; + +/* For consistent manipulation regardless of C or C++ mode */ +typedef struct { + SWIG_funcptr *vtable; +} SWIGIUnknown; + +typedef struct { SWIG_funcptr *vtable; /* vtable for the methods of the wrapped object */ SWIG_funcptr *SWIGWrappedObject_vtable; /* vtable for helper methods */ void *cPtr; /* pointer to the wrapped object */ int cMemOwn; /* memory owned by the proxy? */ LONG refCount; /* reference count */ + void (SWIGSTDCALL *deleteInstance)(SWIGIUnknown *); /* destructor */ ITypeInfo *typeInfo; /* ITypeInfo object for IDispatch */ } SWIGWrappedObject; @@ -160,6 +172,10 @@ long SWIGSTDCALL SWIGRelease1(void *iunk) { LONG res = InterlockedDecrement(&obj->refCount); if (res == 0) { + if (obj->cMemOwn && obj->deleteInstance != 0) { + obj->deleteInstance((SWIGIUnknown *) obj); + } + #ifdef __cplusplus delete obj; #else @@ -214,17 +230,6 @@ HRESULT SWIGSTDCALL SWIGInvoke(SWIGWrappedObject *obj, DISPID dispIdMember, REFI static OLECHAR SWIG_typelib_path[MAX_PATH + 1]; static ITypeLib *SWIG_typelib = NULL; -typedef struct { - SWIG_funcptr *vtable; - SWIG_funcptr newInstance; - LONG refCount; -} SWIGClassFactory; - -/* For consistent manipulation regardless of C or C++ mode */ -typedef struct { - SWIG_funcptr *vtable; -} SWIGIUnknown; - long SWIGSTDCALL SWIGClassFactoryAddRef(SWIGClassFactory *factory) { InterlockedIncrement(&globalRefCount); return InterlockedIncrement(&factory->refCount); @@ -337,7 +342,7 @@ SWIG_funcptr _wrap_opaque_vtable[] = { (SWIG_funcptr) SWIGRelease1, }; -void * SWIGSTDCALL SWIG_wrap_opaque(void *arg) { +void * SWIGSTDCALL SWIG_wrap_opaque(void *arg, int cMemOwn) { #ifdef __cplusplus SWIGWrappedObject *res = new SWIGWrappedObject; #else @@ -346,7 +351,7 @@ void * SWIGSTDCALL SWIG_wrap_opaque(void *arg) { res->vtable = _wrap_opaque_vtable; res->SWIGWrappedObject_vtable = _wrap_opaque_SWIGWrappedObject_vtable; res->cPtr = arg; - res->cMemOwn = 0; + res->cMemOwn = cMemOwn; InterlockedIncrement(&globalRefCount); res->refCount = 1; return (void *) res; diff --git a/Source/Modules/com.cxx b/Source/Modules/com.cxx index 320bda7c1..6cee6bf8b 100644 --- a/Source/Modules/com.cxx +++ b/Source/Modules/com.cxx @@ -232,10 +232,12 @@ public: "#endif\n" " res->vtable = _wrap%s_vtable;\n" " res->SWIGWrappedObject_vtable = NULL;\n" + " /* cPtr and cMemOwn make no sense for the module class */\n" " res->cPtr = NULL;\n" " res->cMemOwn = 0;\n" " InterlockedIncrement(&globalRefCount);\n" " res->refCount = 1;\n" + " res->deleteInstance = 0;\n" " /* GetTypeInfoOfGuid */\n" " ((HRESULT (SWIGSTDCALL *)(ITypeLib *, GUID *, ITypeInfo **)) (((SWIGIUnknown *) SWIG_typelib)->vtable[6]))(SWIG_typelib, &IID_%s, &res->typeInfo);\n" " return (void *) res;\n" @@ -1077,7 +1079,7 @@ public: Printv(proxy_class_vtable_code, "\n};\n\n", NIL); - Printf(proxy_class_vtable_code, "void * SWIGSTDCALL SWIG_wrap%s(void *arg) {\n" + Printf(proxy_class_vtable_code, "void * SWIGSTDCALL SWIG_wrap%s(void *arg, int cMemOwn) {\n" "#ifdef __cplusplus\n" " SWIGWrappedObject *res = new SWIGWrappedObject;\n" "#else\n" @@ -1086,15 +1088,16 @@ public: " res->vtable = _wrap%svtable;\n" " res->SWIGWrappedObject_vtable = _wrap%sSWIGWrappedObject_vtable;\n" " res->cPtr = arg;\n" - " res->cMemOwn = 0;\n" + " res->cMemOwn = cMemOwn;\n" " res->refCount = 0;\n" + " res->deleteInstance = _wrap_delete_%s;\n" " /* GetTypeInfoOfGuid */\n" " ((HRESULT (SWIGSTDCALL *)(ITypeLib *, GUID *, ITypeInfo **)) (((SWIGIUnknown *) SWIG_typelib)->vtable[6]))(SWIG_typelib, &IID_%s, &res->typeInfo);\n" " return (void *) res;\n" "}\n\n", - proxy_class_name, proxy_class_name, proxy_class_name, proxy_class_name); + proxy_class_name, proxy_class_name, proxy_class_name, proxy_class_name, proxy_class_name); - Printf(proxy_class_vtable_defs, "void * SWIGSTDCALL SWIG_wrap%s(void *arg);\n", proxy_class_name); + Printf(proxy_class_vtable_defs, "void * SWIGSTDCALL SWIG_wrap%s(void *arg, int cMemOwn);\n", proxy_class_name); Printv(f_vtables, proxy_class_vtable_code, NIL); Printv(f_vtable_defs, proxy_class_vtable_defs, NIL); |