diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/CallbackProxy.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/CallbackProxy.java index 376c59c9ad..5d2bda3ea7 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/CallbackProxy.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/CallbackProxy.java @@ -142,9 +142,7 @@ void invokeOnThread(final DISPID dispIdMember, final REFIID riid, LCID lcid, WOR PointerByReference ppvObject = new PointerByReference(); IID iid = com.sun.jna.platform.win32.COM.IUnknown.IID_IUNKNOWN; dispatch.QueryInterface(new REFIID(iid), ppvObject); - Unknown rawUnk = new Unknown(ppvObject.getValue()); - long unknownId = Pointer.nativeValue( rawUnk.getPointer() ); - IUnknown unk = CallbackProxy.this.factory.createProxy(IUnknown.class, unknownId, dispatch); + IUnknown unk = CallbackProxy.this.factory.createProxy(IUnknown.class, dispatch); if(targetClass.getAnnotation(ComInterface.class) != null) { rjargs.add(unk.queryInterface(targetClass)); } else { diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Factory.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Factory.java index 990e0dae64..d572fb2535 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Factory.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Factory.java @@ -38,11 +38,9 @@ import java.util.List; public class Factory { - /** - * Creates a utility COM Factory and a ComThread on which all COM calls are executed. - * NOTE: Remember to call factory.getComThread().terminate() at some appropriate point. - * + * Factory keeps track of COM objects - all objects created with this + * factory can be disposed by calling {@link Factory#disposeAll() }. */ public Factory() { assert COMUtils.comIsInitialized() : "COM not initialized"; @@ -90,22 +88,6 @@ public T createProxy(Class comInterface, IDispatch dispatch) { T result = comInterface.cast(proxy); return result; } - - /** only for use when creating ProxyObjects from Callbacks - * - * @param comInterface - * @param unknownId - * @param dispatch - * @return proxy object - */ - T createProxy(Class comInterface, long unknownId, IDispatch dispatch) { - assert COMUtils.comIsInitialized() : "COM not initialized"; - - ProxyObject jop = new ProxyObject(comInterface, unknownId, dispatch, this); - Object proxy = Proxy.newProxyInstance(comInterface.getClassLoader(), new Class[] { comInterface }, jop); - T result = comInterface.cast(proxy); - return result; - } /** * Creates a new COM object (CoCreateInstance) for the given progId and diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java index 9942afb242..decfc3b6d9 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java @@ -55,12 +55,27 @@ /** * This object acts as the invocation handler for interfaces annotated with - * ComInterface. It wraps all (necessary) low level COM calls and executes them - * on a 'ComThread' held by the Factory object. + * ComInterface. It wraps all (necessary) low level COM calls and dispatches + * them through the COM runtime. + * + *

The caller of the methods is responsible for correct initialization of the + * COM runtime and appropriate thread-handling - depending on the choosen + * handling model.

+ * + * @see MSDN - Processes, Threads, and Apartments + * @see MSDN - Understanding and Using COM Threading Models */ public class ProxyObject implements InvocationHandler, com.sun.jna.platform.win32.COM.util.IDispatch, IRawDispatchHandle, IConnectionPoint { + // cached value of the IUnknown interface pointer + // Rules of COM state that querying for the IUnknown interface must return + // an identical pointer value + private long unknownId; + private final Class theInterface; + private final Factory factory; + private final com.sun.jna.platform.win32.COM.IDispatch rawDispatch; + public ProxyObject(Class theInterface, IDispatch rawDispatch, Factory factory) { this.unknownId = -1; this.rawDispatch = rawDispatch; @@ -73,38 +88,11 @@ public ProxyObject(Class theInterface, IDispatch rawDispatch, Factory factory factory.register(this); } - /** when proxy is created for arguments on a call back, they are already on the - * com thread, and hence calling 'getUnknownId' will not work as it uses the ComThread - * however, the unknown pointer value is passed in; - * - * @param theInterface - * @param unknownId - * @param rawDispatch - * @param factory - */ - ProxyObject(Class theInterface, long unknownId, IDispatch rawDispatch, Factory factory) { - this.unknownId = unknownId; - this.rawDispatch = rawDispatch; - this.theInterface = theInterface; - this.factory = factory; - // make sure dispatch object knows we have a reference to it - // (for debug it is usefult to be able to see how many refs are present - int n = this.rawDispatch.AddRef(); - factory.register(this); - } - - - // cached value of the IUnknown interface pointer - // Rules of COM state that querying for the IUnknown interface must return - // an identical pointer value - long unknownId; - - long getUnknownId() { + private long getUnknownId() { assert COMUtils.comIsInitialized() : "COM not initialized"; if (-1 == this.unknownId) { try { - final PointerByReference ppvObject = new PointerByReference(); Thread current = Thread.currentThread(); @@ -144,12 +132,8 @@ public synchronized void dispose() { } } - Class theInterface; - Factory factory; - com.sun.jna.platform.win32.COM.IDispatch rawDispatch; - @Override - public com.sun.jna.platform.win32.COM.IDispatch getRawDispatch() { + public com.sun.jna.platform.win32.COM.IDispatch getRawDispatch() { return this.rawDispatch; } @@ -164,7 +148,7 @@ public com.sun.jna.platform.win32.COM.IDispatch getRawDispatch() { * therefore we can compare the pointers */ @Override - public boolean equals(Object arg) { + public boolean equals(Object arg) { if (null == arg) { return false; } else if (arg instanceof ProxyObject) { @@ -261,7 +245,7 @@ public Object invoke(final Object proxy, final java.lang.reflect.Method method, } // ---------------------- IConnectionPoint ---------------------- - ConnectionPoint fetchRawConnectionPoint(IID iid) throws InterruptedException, ExecutionException, TimeoutException { + private ConnectionPoint fetchRawConnectionPoint(IID iid) throws InterruptedException, ExecutionException, TimeoutException { assert COMUtils.comIsInitialized() : "COM not initialized"; // query for ConnectionPointContainer @@ -466,7 +450,7 @@ public T queryInterface(Class comInterface) throws COMException { } } - IID getIID(ComInterface annotation) { + private IID getIID(ComInterface annotation) { String iidStr = annotation.iid(); if (null != iidStr && !iidStr.isEmpty()) { return new IID(iidStr); @@ -657,11 +641,11 @@ protected HRESULT oleMethod(final int nType, final VARIANT.ByReference pvResult, } - HRESULT hr = pDisp.Invoke(dispId, new REFIID(Guid.IID_NULL), LOCALE_SYSTEM_DEFAULT, - new WinDef.WORD(finalNType), dp, pvResult, pExcepInfo, puArgErr); + HRESULT hr = pDisp.Invoke(dispId, new REFIID(Guid.IID_NULL), LOCALE_SYSTEM_DEFAULT, + new WinDef.WORD(finalNType), dp, pvResult, pExcepInfo, puArgErr); - COMUtils.checkRC(hr, pExcepInfo, puArgErr); - return hr; + COMUtils.checkRC(hr, pExcepInfo, puArgErr); + return hr; } }