summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Jezabek <jezabek@poczta.onet.pl>2008-09-26 00:32:18 +0000
committerJan Jezabek <jezabek@poczta.onet.pl>2008-09-26 00:32:18 +0000
commiteec64d9eeeb7af5e9c545d309ffd151bf479891f (patch)
treee586429f313f6cd2c44e5539b44bc48dd8b2174f
parent5a40aeecc09380d0078f1e224f24e996c7996add (diff)
downloadswig-eec64d9eeeb7af5e9c545d309ffd151bf479891f.tar.gz
QueryInterface now works correctly with opaque types - this provides some type safety. Added a test for this.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/gsoc2008-jezabek@10882 626c5289-ae23-0410-ae9c-e8d60b6d4f22
-rw-r--r--Examples/test-suite/com/Makefile.in3
-rw-r--r--Examples/test-suite/com_opaque_types.i35
-rw-r--r--Lib/com/com.swg9
-rw-r--r--Source/Modules/com.cxx8
4 files changed, 51 insertions, 4 deletions
diff --git a/Examples/test-suite/com/Makefile.in b/Examples/test-suite/com/Makefile.in
index 00ae74d30..93467ceb8 100644
--- a/Examples/test-suite/com/Makefile.in
+++ b/Examples/test-suite/com/Makefile.in
@@ -18,7 +18,8 @@ srcdir = @srcdir@
top_srcdir = @top_srcdir@/..
top_builddir = @top_builddir@/..
-CPP_TEST_CASES =
+CPP_TEST_CASES = \
+ com_opaque_types
include $(srcdir)/../common.mk
diff --git a/Examples/test-suite/com_opaque_types.i b/Examples/test-suite/com_opaque_types.i
new file mode 100644
index 000000000..a0d1ada4f
--- /dev/null
+++ b/Examples/test-suite/com_opaque_types.i
@@ -0,0 +1,35 @@
+%module com_opaque_types
+
+/*
+ * Opaque types have their unique IIDs. This allows to test whether
+ * they work correctly.
+ */
+
+%ignore A;
+%ignore B;
+
+%inline %{
+
+class A {
+ public:
+ int id() { return 1884; }
+};
+
+class B {
+ public:
+ int id() { return 2005; }
+};
+
+int test(A *arg) {
+ return arg->id();
+}
+
+A* fact_A() {
+ return new A;
+}
+
+B* fact_B() {
+ return new B;
+}
+
+%}
diff --git a/Lib/com/com.swg b/Lib/com/com.swg
index 922e168df..e2372de7c 100644
--- a/Lib/com/com.swg
+++ b/Lib/com/com.swg
@@ -704,6 +704,7 @@ HRESULT SWIGSTDCALL _wrap_staticclass_QueryInterface(void *that, GUID *iid, void
}
HRESULT SWIGSTDCALL _wrap_opaque_QueryInterface1(void *that, GUID *iid, void ** ppvObject) {
+ SWIGWrappedObject *obj = (SWIGWrappedObject *) that;
if (SWIGIsEqual(iid, &IID_ISWIGWrappedObject)) {
/* FIXME: This could be more elegant */
SWIGAddRef1(that);
@@ -711,7 +712,8 @@ HRESULT SWIGSTDCALL _wrap_opaque_QueryInterface1(void *that, GUID *iid, void **
return S_OK;
}
- if (SWIGIsEqual(iid, &IID_IUnknown)) {
+ if (SWIGIsEqual(iid, &IID_IUnknown) ||
+ (obj->additionalIID != NULL && SWIGIsEqual(iid, obj->additionalIID))) {
/* FIXME: This could be more elegant */
SWIGAddRef1(that);
*ppvObject = that;
@@ -738,7 +740,7 @@ SWIG_funcptr _wrap_opaque_vtable[] = {
(SWIG_funcptr) SWIGRelease1,
};
-void * SWIGSTDCALL SWIG_wrap_opaque(void *arg, int cMemOwn) {
+void * SWIGSTDCALL SWIG_wrap_opaque(void *arg, int cMemOwn, GUID *iid) {
#ifdef __cplusplus
SWIGWrappedObject *res = new SWIGWrappedObject;
#else
@@ -751,6 +753,9 @@ void * SWIGSTDCALL SWIG_wrap_opaque(void *arg, int cMemOwn) {
res->cMemOwn = cMemOwn;
InterlockedIncrement(&globalRefCount);
res->refCount = 1;
+ res->deleteInstance = NULL;
+ res->outer = NULL;
+ res->additionalIID = iid;
return (void *) res;
}
diff --git a/Source/Modules/com.cxx b/Source/Modules/com.cxx
index ef3596b7c..4afcfb24d 100644
--- a/Source/Modules/com.cxx
+++ b/Source/Modules/com.cxx
@@ -1975,6 +1975,10 @@ public:
Delete(proxy_iid_ident);
}
+ Printf(f_vtable_defs, "GUID IID_I%s = ", classname);
+ formatGUID(f_vtable_defs, proxy_iid, true);
+ Printf(f_vtable_defs, ";\n\n");
+
Printv(proxy_class_forward_def, " interface I$comclassname;\n", NIL);
Printv(proxy_class_def, " [\n object,\n local,\n uuid(", NIL);
@@ -1986,7 +1990,9 @@ public:
Replaceall(proxy_class_forward_def, "$module", module_class_name);
Replaceall(proxy_class_def, "$module", module_class_name);
- Printf(f_vtable_defs, "void * (SWIGSTDCALL * SWIG_wrap%s)(void *, int) = SWIG_wrap_opaque;\n", classname);
+ Printf(f_vtable_defs, "void * SWIGSTDCALL SWIG_wrap%s(void *ptr, int cMemOwn) {\n"
+ " return SWIG_wrap_opaque(ptr, cMemOwn, &IID_I%s);\n"
+ "};\n\n", classname, classname);
Printv(f_proxy_forward_defs, proxy_class_forward_def, NIL);
Printv(f_proxy, proxy_class_def, NIL);