summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Jezabek <jezabek@poczta.onet.pl>2008-07-21 12:17:13 +0000
committerJan Jezabek <jezabek@poczta.onet.pl>2008-07-21 12:17:13 +0000
commit1cb2f1e0e0266bcf427bd17988516f736cd8269b (patch)
tree0a9b64765fa06cb6bd13b29e8bec541d39402740
parent375e76891b707aa150deab475abac428aaa16886 (diff)
downloadswig-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.swg39
-rw-r--r--Source/Modules/com.cxx11
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);