使用 Com4j 订阅 COM 事件
我正在尝试从 Java 连接到专有网络堆栈。该堆栈由 COM 对象提供,我已成功使用 com4j 挂接到它。不幸的是,网络堆栈是基于事件的,因此我需要我的代码来发出请求并订阅提供响应的事件。
每次我尝试订阅事件时,我的代码都会抛出 com4j.ExecutionException,其中包含类似于以下内容的堆栈跟踪:
Exception in thread "main" com4j.ExecutionException: com4j.ComException: 80040200 (Unknown error) : .\invoke.cpp:517
at com4j.ComThread.execute(ComThread.java:203)
at com4j.Task.execute(Task.java:25)
at com4j.Wrapper.advise(Wrapper.java:255)
at com4j.Wrapper.advise(Wrapper.java:18)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com4j.Wrapper.invoke(Wrapper.java:135)
at $Proxy5.advise(Unknown Source)
at main.Main.<init>(Main.java:14)
at main.Main.main(Main.java:131)
Caused by: com4j.ComException: 80040200 (Unknown error) : .\invoke.cpp:517
at com4j.Native.invoke(Native Method)
at com4j.StandardComMethod.invoke(StandardComMethod.java:42)
at com4j.Wrapper$InvocationThunk.call(Wrapper.java:335)
at com4j.Task.execute(Task.java:36)
at com4j.Wrapper$InvocationThunk.invoke(Wrapper.java:324)
at com4j.Wrapper.invoke(Wrapper.java:163)
at com4j.$Proxy9.FindConnectionPoint(Unknown Source)
at com4j.Wrapper$3.call(Wrapper.java:261)
at com4j.Wrapper$3.call(Wrapper.java:255)
at com4j.Task.invoke(Task.java:51)
at com4j.ComThread.run0(ComThread.java:153)
at com4j.ComThread.run(ComThread.java:134)
首先,我认为我的代码或 COM 对象出了问题,所以我回到了基础知识并尝试实现 com4j 源附带的 iTunes 示例。他们的示例如下所示:
public class Main {
public static void main(String[] args) throws Exception {
IiTunes iTunes = ClassFactory.createiTunesApp();
EventCookie cookie = iTunes.advise(_IiTunesEvents.class, new _IiTunesEvents() {
public void onDatabaseChangedEvent(Object deletedObjectIDs, Object changedObjectIDs) {
System.out.println("Database changed:" + deletedObjectIDs + "," + changedObjectIDs);
}
public void onPlayerPlayEvent(Object iTrack) {
System.out.println("Playing " + iTrack);
}
public void onPlayerStopEvent(Object iTrack) {
System.out.println("Stopped " + iTrack);
}
});
IITTrack track = iTunes.currentTrack();
if(track==null) {
System.out.println("Nothing is playing");
} else {
System.out.println("Now playing: "+ track.name());
}
System.out.println("Listening to events (will quit in 15 seconds)");
System.out.println("Play/stop songs in iTunes and see what happens");
Thread.sleep(15000);
cookie.close();
}
}
当我尝试在我的计算机上运行此示例时,我收到了上述异常。
EventCookie cookie = iTunes.advise(_IiTunesEvents.class, new _IiTunesEvents() {...
有人知道为什么我无法订阅 COM 对象引发的事件吗?
我已经对我实际尝试包装的对象尝试了类似的代码,但它以同样的方式失败,这让我相信这个问题与我的开发环境有关。
I'm trying to hook into a proprietary network stack from Java. The stack is provided by a COM object, and I've managed to hook into it using com4j. Unfortunately, the network stack is event-based, so I need my code to issue requests and subscribe to events that provide the responses.
Every time I try to subscribe to events, my code throws a com4j.ExecutionException that contains a stack trace similar to the following:
Exception in thread "main" com4j.ExecutionException: com4j.ComException: 80040200 (Unknown error) : .\invoke.cpp:517
at com4j.ComThread.execute(ComThread.java:203)
at com4j.Task.execute(Task.java:25)
at com4j.Wrapper.advise(Wrapper.java:255)
at com4j.Wrapper.advise(Wrapper.java:18)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com4j.Wrapper.invoke(Wrapper.java:135)
at $Proxy5.advise(Unknown Source)
at main.Main.<init>(Main.java:14)
at main.Main.main(Main.java:131)
Caused by: com4j.ComException: 80040200 (Unknown error) : .\invoke.cpp:517
at com4j.Native.invoke(Native Method)
at com4j.StandardComMethod.invoke(StandardComMethod.java:42)
at com4j.Wrapper$InvocationThunk.call(Wrapper.java:335)
at com4j.Task.execute(Task.java:36)
at com4j.Wrapper$InvocationThunk.invoke(Wrapper.java:324)
at com4j.Wrapper.invoke(Wrapper.java:163)
at com4j.$Proxy9.FindConnectionPoint(Unknown Source)
at com4j.Wrapper$3.call(Wrapper.java:261)
at com4j.Wrapper$3.call(Wrapper.java:255)
at com4j.Task.invoke(Task.java:51)
at com4j.ComThread.run0(ComThread.java:153)
at com4j.ComThread.run(ComThread.java:134)
At first, I figured that something was wrong with my code or with my COM object, so I went back to basics and tried to implement the iTunes example that ships with the com4j source. Their example looks like this:
public class Main {
public static void main(String[] args) throws Exception {
IiTunes iTunes = ClassFactory.createiTunesApp();
EventCookie cookie = iTunes.advise(_IiTunesEvents.class, new _IiTunesEvents() {
public void onDatabaseChangedEvent(Object deletedObjectIDs, Object changedObjectIDs) {
System.out.println("Database changed:" + deletedObjectIDs + "," + changedObjectIDs);
}
public void onPlayerPlayEvent(Object iTrack) {
System.out.println("Playing " + iTrack);
}
public void onPlayerStopEvent(Object iTrack) {
System.out.println("Stopped " + iTrack);
}
});
IITTrack track = iTunes.currentTrack();
if(track==null) {
System.out.println("Nothing is playing");
} else {
System.out.println("Now playing: "+ track.name());
}
System.out.println("Listening to events (will quit in 15 seconds)");
System.out.println("Play/stop songs in iTunes and see what happens");
Thread.sleep(15000);
cookie.close();
}
}
When I try to run this example on my machine, I get the above exception on the line
EventCookie cookie = iTunes.advise(_IiTunesEvents.class, new _IiTunesEvents() {...
Does anybody have any insight as to why I can't subscribe to events thrown by the COM object?
I've tried similar code with the object that I'm actually trying to wrap, and it fails in the same way, which leads me to believe that the issue has to do with my development environment.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
该线程已经有几个月了,但是您是否使用了生成的事件接口并检查了正确的
@IID("{...}")
?就我而言,当我使用 OLE/COM 对象查看器将其与 typelib(.tlb
文件)中的同一类进行比较时,这是错误的。使用正确的
@IID
创建公共抽象类后,它对我来说工作得很好。The thread is already some months old, but did you use the generated event interface and check for the correct
@IID("{...}")
? In my case this was wrong when I compared it with the same class in the typelib (.tlb
file) with OLE/COM Object Viewer.After creating a public abstract class with the correct
@IID
it worked fine for me.