首页 文章

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

提问于
浏览
1

我工作的公司需要一些软件的功能,因为它可以应用于多个产品,这些产品是用不同的语言编写的,虽然它们只在Windows上运行,但它似乎是在COM服务器中实现它的一个很好的选择 . 我使用python和pywin32扩展编写了COM服务器,因此访问它是后期绑定,我相信IDispatch .

我现在正在尝试为COM服务器创建Java绑定,因为它需要使用调度接口,我决定使用JACOB来访问COM(它似乎是最近更新的项目之一并符合我们的需求) . 作为一个相当新的COM,并没有真正看到COM服务器包装的库中多线程的任何问题,我最初很少关注COM线程,所以它是COM对象的Java绑定我没有使用提供的任何线程的东西通过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对象的.com.ComThread.Release() . 此外,文档还建议我可能希望JACOB创建一个主STA,这也意味着在关闭应用程序时调用退出主STA .

我的问题是,在一个线程的开头调用这些东西似乎并不能很好地适应Java的做事方式,我有什么方法可以尝试将应用程序的其余部分与COM的这些特性隔离开来,特别是在穿线区域?

我考虑过,因为应用程序使用我的绑定而不是直接使用COM对象,这些东西是否可以在这些包装类中处理?但是我似乎只想在访问COM对象的包装器对象的每个方法中调用ComThread.InitMTA()和ComThread.Release() . 这感觉效率低下,但我不知道对ComThread.InitMTA()和ComThread.Release()的调用实际上是多少,它可能没有最初看起来那么糟糕 .

我的另一个想法是,在使用这个库的早期阶段,我认为我们实际上并没有使用COM服务器发布任何东西,所以可能有更好的技术可以使用(例如RPC,可能是XMLRPC)?这样的改变现在可能不会太痛苦 .

为了提供关于库正在做什么的一些上下文,它主要将各种语音输出API包装成一个(例如,提供用于访问SAPI4,SAPI5和其他一些的公共接口) . 所以大多数电话只是告诉系统说些什么,沉默话语或改变设置 . 一般来说,与库的通信非常简单(我认为返回一个字符串数组就像它得到的那样复杂) .

1 回答

  • 0

    这听起来像是面向方面编程(AOP)的一个非常好的候选者 . java中的主导框架是AspectJ,但是大多数人在Spring-AOP的上下文中使用它 . 根据您的要求和架构,您可以采用不同的方向:

    • 编译时编织 - 在编译时通过特殊编译器应用切入点和建议("weaved")

    • 加载时编织 - 由JVM代理在运行时应用切入点和建议

    • 动态代理 - 通过在动态代理外观中包装推荐类来应用运行时的切入点和建议(这就是Spring-AOP的工作方式)

    发现这个相当不错的写作在aspectj weaving .

相关问题