Skip to content

Commit db7f3a5

Browse files
committed
Add COM4J.wrapSta for wrapping STA com objects
Objects wrapped in this way can only be called from the same thread they were created by (and wrapped in). When using these wrapped objects calls to the COM object are done in the same thread instead of using a second thread. This has the disadvantage that these objects can't be passed around and used from anywhere, but where a COM object has to be called from a specific thread it means they can be used (mostly only a problem when the Java code is running in the same process as an in-process COM server). Fixes kohsuke#68
1 parent 1e690b8 commit db7f3a5

File tree

8 files changed

+586
-308
lines changed

8 files changed

+586
-308
lines changed

runtime/src/main/java/com4j/COM4J.java

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,33 @@ public T call() {
142142
}.execute();
143143
}
144144

145+
/**
146+
* Wraps an externally obtained single-threaded apartment interface pointer from the current
147+
* thread into a COM wrapper object.
148+
* <p>
149+
* This method must be called by the same thread that the COM object belongs to.
150+
* Object wrappers created with this method can only be accessed from that thread.
151+
* <p>
152+
* This method doesn't call addRef on the given interface pointer. Instead, this method
153+
* takes over the ownership of the given pointer.
154+
* </p>
155+
*
156+
* @param primaryInterface
157+
* The interface type to wrap the pointer into.
158+
* @param ptr
159+
* The rar interface pointer value.
160+
*/
161+
public static<T extends Com4jObject>
162+
T wrapSta( final Class<T> primaryInterface, final long ptr ) throws ComException {
163+
ComThread thread = ComThreadSingle.get();
164+
return new Task<T>() {
165+
@Override
166+
public T call() {
167+
return Wrapper.create(primaryInterface,ptr);
168+
}
169+
}.execute(thread);
170+
}
171+
145172
/**
146173
* Gets an already running object from the running object table.
147174
*
@@ -387,7 +414,8 @@ public static ByteBuffer createBuffer( long ptr, int size ) {
387414
* @see #removeListener(ComObjectListener)
388415
*/
389416
public static void addListener( ComObjectListener listener ) {
390-
ComThread.get().addListener(listener);
417+
ComThreadMulti.get().addListener(listener);
418+
ComThreadSingle.get().addListener(listener);
391419
}
392420

393421
/**
@@ -400,7 +428,8 @@ public static void addListener( ComObjectListener listener ) {
400428
* @see #addListener(ComObjectListener)
401429
*/
402430
public static void removeListener( ComObjectListener listener ) {
403-
ComThread.get().removeListener(listener);
431+
ComThreadMulti.get().removeListener(listener);
432+
ComThreadSingle.get().removeListener(listener);
404433
}
405434

406435
/**
@@ -416,7 +445,8 @@ public static void removeListener( ComObjectListener listener ) {
416445
* After this method is invoked, a thread can still go use other COM resources.
417446
*/
418447
public static void cleanUp() {
419-
ComThread.detach();
448+
ComThreadMulti.detach();
449+
ComThreadSingle.detach();
420450
}
421451

422452
/**

0 commit comments

Comments
 (0)