【问题标题】:Calling Java code from a C# COM DLL that’s used by a WIN32 application?从 WIN32 应用程序使用的 C# COM DLL 调用 Java 代码?
【发布时间】:2009-09-15 19:35:30
【问题描述】:

我有一个非常简单的问题。我有一个用 Delphi 2007 为 WIN32 编写的应用程序。它使用一个 C# DLL,该 DLL 通过它的 COM 接口导入到项目中,并使用一个简单的技巧来避免注册 COM 对象。但是现在我有一个 Java 生成的 .JAR 文件,我想从我的应用程序中调用它。虽然我可以访问 Delphi 和 C# 代码,但我无法访问 Java 代码。

我可以做两件事。要么我从 Delphi 代码调用 Java 类,然后再从 Delphi 代码再次调用的 C# 代码调用该类。或者我只是直接从 C# 调用 Java 代码。 (再次从 Delphi 调用。)

我知道这是一个复杂的设置。 Delphi 应用程序包含一个 GUI 和一些用于一些特殊硬件的通信模块。这些没有 .NET 驱动程序。 C# 代码用于维护数据库通信,并包含一些与 CardSpace 和其他安全选项相关的逻辑。 Java 类是一个第三方编码模块,由外部方创建,它对数据库中的数据计算特殊的哈希码并进行一些额外的处理并控制另一块硬件。

最大的问题:没有网络通讯!它将在没有安装网络硬件的特殊计算机上运行。它是一个独立的 Windows XP 系统。虽然 COM、Java 和 .NET 都可以,但我不能在这个系统上使用任何 TCP/IP 通信。

如果我接受,这将是我的下一个项目。已经让我头疼了,所以我想我会跳过这个机会,尽管它确实有几种不同语言的有趣混合。我想我会告诉他们投资 6 位数来购买新硬件,而不是花费近 5 位数来完成 28 天的工作......


关于我可以分享的项目的一些细节:

Delphi 代码能够通过 COM 端口连接到 PBX 系统,用于发送传真、发送和接收 SMS 消息,并在拨打电话后只需用电话输入数字即可接收简单的命令。整个系统具有为此编写的,全部基于WIN32代码。

Java 代码是一个客户端模块,用于与机器人系统进行通信,该系统监控环境、处理一些精细对象并持续测量这些对象。它在 Java 中,因此与平台无关。 Java 客户端和机器人硬件之间的通信是通过网络完成的,并且网络硬件/驱动程序不喜欢通过这个网络进行额外的通信。 (这就是它被尽可能禁用的原因。甚至 Windows 也不会获得更新。)

C# 代码用于从 Java 模块收集数据并将这些数据实际存储在内存中,并定期以 XML 格式备份,以防万一发生意外。这是为了与 Java 模块和其他一些处理复杂计算的模块进行通信,这些计算是用客户自己开发的 .NET 兼容的特定领域语言编写的。这些模块不支持 COM,因此是 c# 包装器。

客户现在需要一名操作员靠近硬件来操作机器人。他可以升级硬件,但要花很多钱,但这会给他更好的远程访问,更换古老的机器人和其他硬件需要花费大约 250,000 欧元,或者他支付一些开发人员的十分之一来让他当前的硬件升级照着做。就个人而言,我认为他不应该是个小气鬼,但他只是想估计一下开发人员的解决方案会花费他多少。代码更改并不大,因为大部分功能已经存在。它只是将所有这些组合在一起,没有任何 TCP/IP 通信,这使它变得更加复杂。

基本上,他们想要给出的指令是加快或减慢速度,偶尔发送报告并在出现问题时发送短信警告。现在,他们有一个坐在屏幕旁边的手术室,整天喝咖啡,同时阅读一些报纸或其他杂志。虽然这几天很有趣,但他无法找到一个愿意一直这样做的人,24/7。 (是的,他们日夜工作,包括周末。)

基本上,这就是我自己所知道的一切。甚至还没有看到需要安装它的 PC,但是他们以相同的方式配置了一些 PC,因此一旦需要,我就可以尝试使用它。 (而且调试起来也很麻烦。)


最后,我提出了成本估算,并提出了一个足够高的数字来说服我的未来雇主进行硬件升级。更贵,但它会保持它的可靠性。

正因为如此,这个Q才刚刚成为学术...

【问题讨论】:

  • 在我看来,Delphi 与此无关。 COM 也没有。您正在尝试从 C# 代码调用 Java 代码。您最初如何进入 C# 代码无关紧要。这一启示使您的情况变得不那么复杂。
  • 虽然确实如此,但它确实给内存模型增加了一些限制和其他一些小限制。它主要限制了我如何使 C# 和 Java 相互通信的方式。 (如果不是烦人的 Delphi/WIN32 代码,我本可以反过来,通过它的 COM 接口从 Java 调用 C#。
  • 我能看到内存模型或主机应用程序与它有任何关系的唯一方法是,如果您希望 Java 代码直接写入某些 Delphi 分配的内存,必须通过 COM 编组.所以不要那样做。让 Java 代码写入 C# 分配的缓冲区,因为我假设 IKVM 和 JNBridge 必须支持作为基本功能,然后将其封送回 Delphi,就像您对 DLL 中的其他所有内容所做的一样。

标签: c# java delphi


【解决方案1】:

另一个选项是IKVM。它是 .NET 的 Java 实现。请查看this related question,那里的答案可能会对您有所帮助。

【讨论】:

  • 我已经考虑了一会儿,但我不控制 Java 代码,因此不能保证它会工作。可能存在一些与此相关的许可证问题,但如果需要,可以忽略一些小问题。
【解决方案2】:

JNBridge 提供 Java 到 .NET 的桥接器(反之亦然)。它受到商业支持,相对便宜,而且效果很好。它具有低延迟,并且不需要 TCP/IP 或网络通信。您无需访问 Java 代码即可通过网桥从 .NET 调用它。

【讨论】:

  • 看起来很有希望。项目预算允许成本。现在我所需要的只是解决一些小细节。 :-)
【解决方案3】:

无论是否安装了任何网络硬件,独立的Windows XP 系统很可能仍然有本地 TCP/IP 网络可用。您可以让程序在localhost 地址 (127.0.0.1) 上的 TCP 端口上侦听,其他服务连接到它们以通过您选择的任何协议交换信息。带有 REST 的 HTTP 可能是一个合适的选择。

这可能比尝试将所有这些技术集成到一个弗兰肯程序中要少得多。

【讨论】:

  • 其实要求是本项目中没有使用TCP/IP的代码。所以没有开放的端口。我猜系统安装了一个非常严格的防火墙来阻止它,虽然我还不知道确切的细节。
  • 听起来很狡猾,尤其是考虑到其他实现限制。至少听起来你有能力选择不从事这个项目。 :)
  • 是的。我被要求先进行成本估算,以便他们可以继续使用当前硬件几年。这让我可以确定它是否可行,以及我是否想这样做。它让他们看到它是否真的比购买更好的硬件解决方案便宜很多。现在,我比新硬件选项便宜十倍,如果我仍然可以在 28 天内做到这一点而无需任何额外费用。 (不幸的是,还有其他成本。)只要我的估计明显低于硬件成本的一半,就会考虑。
【解决方案4】:

我是jni4net 的作者,它是 JVM 和 CLR 之间的开源进程内桥梁。它建立在 JNI 和 PInvoke 之上。无需 C/C++ 代码。希望对你有帮助。

【讨论】:

  • 自从我说服管理层这样的解决方案会变得过于复杂和昂贵,这个问题就变成了学术问题。
猜你喜欢
  • 2011-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-26
  • 1970-01-01
  • 2010-09-12
相关资源
最近更新 更多