java - 如何在多个 Java 线程中使用 COM 服务器

标签 java multithreading com

我工作的公司想要一些软件的一些功能,因为它可以适用于多种产品,并且这些产品是用不同的语言编写的,虽然都只能在 Windows 上运行,但在 COM 服务器中实现它似乎是一个不错的选择。我使用 python 和 pywin32 扩展编写了 COM 服务器,因此对它的访问是后期绑定(bind),我相信 IDispatch。

我现在正在尝试为COM服务器创建Java绑定(bind),因为它需要使用调度接口(interface),我决定使用JACOB来访问COM(它似乎是最近更新的项目之一并且符合我们的需求)。由于对 COM 相当陌生,并且在 COM 服务器包装的库中并没有真正看到任何多线程问题,所以我一开始很少关注 COM 线程,因此对于 COM 对象的 Java 绑定(bind),我没有使用提供的任何线程内容由 JACOB 编写,对其进行简单测试,在 Oracle 的 JVM 中运行良好。

然而,很明显我不能忽视 COM 线程。一个问题是 Java 产品是使用 Excelsior Jet 编译的,由于某种原因,它没有在 Java 中释放 COM 对象,因此 COM 服务器(这是一个单独的 .exe)在退出应用程序后继续运行。另一个问题是我们确实需要在多个线程中使用 COM 对象,我最初的方法是遇到 COM 对象无法在多个线程中使用的问题。

我已经阅读了 JACOB 发行版中关于如何处理 COM 对象的文档(关于引用计数 VS GC 的文档和关于多线程的文档)。我相信我理解这些以及如何在多个线程中使用 COM 对象并正确释放它们(对每个线程使用 JACOB 的 ComThread.Release() 确实会导致 Excelsior Jet 释放 COM 对象)。

我的想法是,多线程公寓应该适合 COM 服务器,因此根据 JACOB 文档,这只需要每个线程在使用 COM 对象之前调用 com.jacob.com.ComThread.InitMTA() ,然后调用com.jacob.com.ComThread.Release() 在每个使用 COM 对象的线程结束时。该文档还表明我可能希望 JACOB 创建一个主 STA,因此这也意味着在应用程序关闭时调用退出主 STA。

我的问题是,这种在线程开始时调用的方式似乎不太适合 Java 的处理方式,有什么方法可以尝试将应用程序的其余部分与 COM 的这些特性隔离开来,特别是在线程区域?

我考虑过,由于应用程序正在使用我的绑定(bind)而不是直接使用 COM 对象,因此这些内容可以在这些包装类中处理吗?然而,我似乎只在访问 COM 对象的包装对象的每个方法中调用 ComThread.InitMTA() 和 ComThread.Release() 。这感觉效率很低,但是我不知道有多少对 ComThread.InitMTA() 和 ComThread.Release() 的调用实际上做了,所以它可能不像最初看起来那么糟糕。

我的另一个想法是,使用这个库还很早,我认为我们实际上还没有使用 COM 服务器发布任何东西,所以可能有更好的技术可以使用(例如 RPC,可能是 XMLRPC) ?目前做出这样的改变可能不会太痛苦。

为了提供有关该库正在做什么的一些上下文,它主要将各种语音输出 API 包装成一个(例如,提供一个用于访问 SAPI4、SAPI5 和其他一些 API 的通用接口(interface))。因此,大多数调用只是告诉系统说些什么、静音或更改设置。一般来说,与库的通信非常简单(我认为返回一个字符串数组是最复杂的)。

最佳答案

这听起来非常适合某些面向方面编程(AOP)。 java中的主导框架是AspectJ ,但大多数人在 Spring-AOP 的上下文中使用它。根据您的要求和架构,您可以采用不同的方向:

  1. 编译时编织 - 切入点和建议由特殊编译器在编译时应用(“编织”)
  2. 加载时编织 - 切入点和建议由 JVM 代理在运行时应用
  3. 动态代理 - 通过将建议类包装在动态代理外观中来在运行时应用切入点和建议(这就是 Spring-AOP 的做法)

aspectj weaving 上发现这篇相当不错的文章.

关于java - 如何在多个 Java 线程中使用 COM 服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12894257/

相关文章:

java - 查询有关简单线程示例的输出

安装了 Java SE 7,但不支持开关中的字符串

c++ - 渲染时加载纹理 (OpenGL)

iphone - 启动应用程序时,iPhone OS将创建什么样的进程和线程?

java - 如果 Itunes :Keep iTunes Folder Organized is set programmatically on Windows,我该如何解决

c# - 如何在 C# 中生成 UUID

java - 如何在 Spring-data JPA 的名称中使用下划线 "_"映射类属性

java - getpath 函数的路径无效

Java Spring Boot - 用于在后台运行的异步数据库操作的 CommandLineRunner

com - iTunes COM/AppleScript - 播客 RSS