From: <je...@us...> - 2008-08-28 20:39:21
|
Revision: 10798 http://swig.svn.sourceforge.net/swig/?rev=10798&view=rev Author: jezabek Date: 2008-08-28 20:39:17 +0000 (Thu, 28 Aug 2008) Log Message: ----------- Added better support for exceptions - now a description is added. Added corresponding run-test. Fixed a serious typo in the deallocation code for the module class. Modified Paths: -------------- branches/gsoc2008-jezabek/Examples/test-suite/com/virtual_poly_runme.c branches/gsoc2008-jezabek/Lib/com/com.swg branches/gsoc2008-jezabek/Source/Modules/com.cxx Added Paths: ----------- branches/gsoc2008-jezabek/Examples/test-suite/com/throw_exception_runme.c Added: branches/gsoc2008-jezabek/Examples/test-suite/com/throw_exception_runme.c =================================================================== --- branches/gsoc2008-jezabek/Examples/test-suite/com/throw_exception_runme.c (rev 0) +++ branches/gsoc2008-jezabek/Examples/test-suite/com/throw_exception_runme.c 2008-08-28 20:39:17 UTC (rev 10798) @@ -0,0 +1,83 @@ +#define CINTERFACE +#include <stdio.h> +#include <windows.h> + +#ifndef MSVC +/* This is a workaround for a VC specific attribute */ +#define __RPC__deref_out +#endif + +#ifdef __DMC__ +#define __RPCNDR_H_VERSION__ ( 450 ) +#endif + +#include "throw_exception/throw_exception_generated.h" + +void check_message(wchar_t *expected_msg) { + IErrorInfo *iei = NULL; + wchar_t *descr = NULL; + + GetErrorInfo(0, &iei); + + iei->lpVtbl->GetDescription(iei, &descr); + iei->lpVtbl->Release(iei); + + if (wcscmp(expected_msg, descr)) { + fprintf(stderr, "Incorrect message description\n"); + exit(1); + } + + /* Should we release descr? */ + CoTaskMemFree(descr - 2); +} + +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { + Ithrow_exception *te = NULL; + IFooStatic *fs = NULL; + IFoo *foo = NULL; + IErrorInfo *iei = NULL; + HRESULT hres; + + CoInitialize(NULL); + + CoCreateInstance(&CLSID_throw_exceptionImpl, NULL, CLSCTX_INPROC_SERVER, &IID_Ithrow_exception, (void **) &te); + + /* Construct Foo object */ + te->lpVtbl->get_Foo(te, &fs); + fs->lpVtbl->new_Foo(fs, &foo); + + hres = foo->lpVtbl->test_int(foo); + + if (hres != E_ABORT) { + fprintf(stderr, "Exception should have been thrown\n"); + exit(1); + } + + check_message(L"C++ int exception thrown"); + + hres = foo->lpVtbl->test_msg(foo); + + if (hres != E_ABORT) { + fprintf(stderr, "Exception should have been thrown\n"); + exit(1); + } + + check_message(L"C++ char const * exception thrown"); + + hres = foo->lpVtbl->test_cls(foo); + + if (hres != E_ABORT) { + fprintf(stderr, "Exception should have been thrown\n"); + exit(1); + } + + check_message(L"C++ Error exception thrown"); + + foo->lpVtbl->Release(foo); + fs->lpVtbl->Release(fs); + te->lpVtbl->Release(te); + + CoUninitialize(); + + return 0; +} Modified: branches/gsoc2008-jezabek/Examples/test-suite/com/virtual_poly_runme.c =================================================================== --- branches/gsoc2008-jezabek/Examples/test-suite/com/virtual_poly_runme.c 2008-08-24 12:59:17 UTC (rev 10797) +++ branches/gsoc2008-jezabek/Examples/test-suite/com/virtual_poly_runme.c 2008-08-28 20:39:17 UTC (rev 10798) @@ -147,5 +147,7 @@ vp->lpVtbl->Release(vp); + CoUninitialize(); + return 0; } Modified: branches/gsoc2008-jezabek/Lib/com/com.swg =================================================================== --- branches/gsoc2008-jezabek/Lib/com/com.swg 2008-08-24 12:59:17 UTC (rev 10797) +++ branches/gsoc2008-jezabek/Lib/com/com.swg 2008-08-28 20:39:17 UTC (rev 10798) @@ -341,6 +341,7 @@ SWIGTYPE[], SWIGTYPE[ANY] %{ + SWIG_SetErrorInfo(L"C++ $1_type exception thrown", L"", &IID_IUnknown); return $null; %} @@ -376,6 +377,7 @@ SWIG_funcptr *vtable; /* vtable for the methods of the wrapped object */ SWIG_funcptr *SWIGWrappedObject_vtable; /* vtable for helper methods */ SWIG_funcptr *aggregated_vtable; /* vtable to present to the outer object */ + SWIG_funcptr *ISupportErrorInfo_vtable; void *cPtr; /* pointer to the wrapped object */ int cMemOwn; /* memory owned by the proxy? */ LONG refCount; /* reference count */ @@ -392,6 +394,31 @@ return memcmp(a, b, sizeof(GUID)) == 0; } +void SWIG_SetErrorInfo(const wchar_t *msg, const wchar_t *source, const GUID *guid) { + SWIGIUnknown *icei; + IErrorInfo *iei; + + CreateErrorInfo((ICreateErrorInfo **) &icei); + + /* SetGUID */ + ((HRESULT (SWIGSTDCALL *)(SWIGIUnknown *, const GUID *)) icei->vtable[3])(icei, guid); + + /* SetSource */ + ((HRESULT (SWIGSTDCALL *)(SWIGIUnknown *, LPCOLESTR)) icei->vtable[4])(icei, source); + + /* SetDescription */ + ((HRESULT (SWIGSTDCALL *)(SWIGIUnknown *, LPCOLESTR)) icei->vtable[5])(icei, msg); + + /* Use QueryInterface to convert ICreateErrorInfo to IErrorInfo */ + ((HRESULT (SWIGSTDCALL *)(SWIGIUnknown *, REFGUID, LPVOID *)) icei->vtable[0])(icei, IID_IErrorInfo, (void **) &iei); + + SetErrorInfo(0, iei); + + /* Release both object references */ + ((LONG (SWIGSTDCALL *)(SWIGIUnknown *)) icei->vtable[2])(icei); + ((LONG (SWIGSTDCALL *)(SWIGIUnknown *)) ((SWIGIUnknown *) iei)->vtable[2])((SWIGIUnknown *) iei); +} + long SWIGSTDCALL SWIGAddRef1(void *iunk) { SWIGWrappedObject *obj = (SWIGWrappedObject *) iunk; @@ -414,6 +441,10 @@ return InterlockedIncrement(&obj->refCount); } +long SWIGSTDCALL SWIGAddRef4(void *iunk) { + return SWIGAddRef1((void **)iunk - 3); +} + long SWIGSTDCALL SWIGRelease1(void *iunk) { SWIGWrappedObject *obj = (SWIGWrappedObject *) iunk; @@ -464,6 +495,22 @@ return res; } +long SWIGSTDCALL SWIGRelease4(void *iunk) { + return SWIGRelease1((void **)iunk - 3); +} + +HRESULT SWIGSTDCALL SWIGQueryInterface4(void *iunk, GUID *iid, void **ppvObject) { + /* + * Forwards the call to the main vtable. This is not optimal as the call cannot + * be inlined. However generating a separate function for each class is + * rather inconvenient. + */ + + SWIGWrappedObject *obj = (SWIGWrappedObject *) ((void **) iunk - 3); + + return ((HRESULT (SWIGSTDCALL *)(void *, GUID *, void **)) obj->vtable[0]) ((void *) obj, iid, ppvObject); +} + void * SWIGSTDCALL SWIGGetCPtr(void *iunk) { SWIGWrappedObject *obj = (SWIGWrappedObject *) ((void **)iunk - 1); @@ -500,6 +547,17 @@ return hres; } +HRESULT SWIGSTDCALL SWIGInterfaceSupportsErrorInfo(void *ignored, GUID *riid) { + return S_OK; +} + +SWIG_funcptr ISupportErrorInfo_vtable[] = { + (SWIG_funcptr) SWIGQueryInterface4, + (SWIG_funcptr) SWIGAddRef4, + (SWIG_funcptr) SWIGRelease4, + (SWIG_funcptr) SWIGInterfaceSupportsErrorInfo +}; + static OLECHAR SWIG_typelib_path[MAX_PATH + 1]; static ITypeLib *SWIG_typelib = NULL; @@ -593,7 +651,7 @@ } SWIGClassDescription_t; void _wrap_delete_staticclass(void *arg) { - SWIGWrappedObject *obj = (SWIGWrappedObject *) obj; + SWIGWrappedObject *obj = (SWIGWrappedObject *) arg; #ifdef __cplusplus delete obj; #else @@ -609,6 +667,7 @@ #endif res->vtable = vtable; res->SWIGWrappedObject_vtable = NULL; + res->ISupportErrorInfo_vtable = ISupportErrorInfo_vtable; /* cPtr and cMemOwn make no sense for static classes */ res->cPtr = NULL; res->cMemOwn = 0; @@ -628,10 +687,13 @@ if (SWIGIsEqual(iid, &IID_IUnknown) || SWIGIsEqual(iid, &IID_IDispatch) || (obj->additionalIID != NULL && SWIGIsEqual(iid, obj->additionalIID))) { - /* FIXME: This could be more elegant */ SWIGAddRef1(that); *ppvObject = that; return S_OK; + } else if (SWIGIsEqual(iid, &IID_ISupportErrorInfo)) { + SWIGAddRef1(that); + *ppvObject = &obj->ISupportErrorInfo_vtable; + return S_OK; } return E_NOINTERFACE; @@ -680,6 +742,7 @@ #endif res->vtable = _wrap_opaque_vtable; res->SWIGWrappedObject_vtable = _wrap_opaque_SWIGWrappedObject_vtable; + res->ISupportErrorInfo_vtable = ISupportErrorInfo_vtable; res->cPtr = arg; res->cMemOwn = cMemOwn; InterlockedIncrement(&globalRefCount); Modified: branches/gsoc2008-jezabek/Source/Modules/com.cxx =================================================================== --- branches/gsoc2008-jezabek/Source/Modules/com.cxx 2008-08-24 12:59:17 UTC (rev 10797) +++ branches/gsoc2008-jezabek/Source/Modules/com.cxx 2008-08-28 20:39:17 UTC (rev 10798) @@ -1435,6 +1435,10 @@ " SWIGAddRef1(that);\n" " *ppvObject = &obj->SWIGWrappedObject_vtable;\n" " return S_OK;\n" + " } else if (SWIGIsEqual(iid, &IID_ISupportErrorInfo)) {\n" + " SWIGAddRef1(that);\n" + " *ppvObject = &obj->ISupportErrorInfo_vtable;\n" + " return S_OK;\n" " }\n\n"); Printf(proxy_class_vtable_code, " if (SWIGIsEqual(iid, &IID_IUnknown) ||\n" @@ -1460,7 +1464,6 @@ } Printf(proxy_class_vtable_code, ") {\n" - " /* FIXME: This could be more elegant */\n" " SWIGAddRef1(that);\n" " *ppvObject = obj;\n" " return S_OK;\n" @@ -1497,6 +1500,10 @@ " SWIGAddRef3(that);\n" " *ppvObject = &obj->SWIGWrappedObject_vtable;\n" " return S_OK;\n" + " } else if (SWIGIsEqual(iid, &IID_ISupportErrorInfo)) {\n" + " SWIGAddRef1(that);\n" + " *ppvObject = &obj->ISupportErrorInfo_vtable;\n" + " return S_OK;\n" " }\n\n"); /* Special case for aggregation - IUnknown has to be different */ @@ -1681,6 +1688,7 @@ " res->vtable = _wrap%svtable;\n" " res->SWIGWrappedObject_vtable = _wrap%sSWIGWrappedObject_vtable;\n" " res->aggregated_vtable = _wrap%saggregated_vtable;\n" + " res->ISupportErrorInfo_vtable = ISupportErrorInfo_vtable;\n" " res->cPtr = arg;\n" " res->cMemOwn = cMemOwn;\n" " res->outer = NULL;\n" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |