如果我希望从 PowerBuilder(10 或 11.5)引用 .NET dll,以下哪项是最佳实践?
1) 将 dll 注册为 COM 对象,并通过 OleObject 使用 COM 对象 2) 升级到 11.5,并转换为 PB.NET,这样我就可以在 PowerBuilder 代码中实际拥有 C# 块 3) 另一种方法
使用这些方法我应该注意哪些事项?
如果我希望从 PowerBuilder(10 或 11.5)引用 .NET dll,以下哪项是最佳实践?
1) 将 dll 注册为 COM 对象,并通过 OleObject 使用 COM 对象 2) 升级到 11.5,并转换为 PB.NET,这样我就可以在 PowerBuilder 代码中实际拥有 C# 块 3) 另一种方法
使用这些方法我应该注意哪些事项?
需要注意的事项:
第一种方法(COM Wrapper)适用于任何版本的 PowerBuilder,包括 11.5 及更高版本,当您只想创建 Win32 应用程序时。但是,您可以实际执行的操作存在一些限制。该程序集必须标记为 COM 可见。您要调用的方法必须是公开的。如果方法过载,您可能会遇到版本控制问题。异常也是一个问题,您必须在 .Net 端实现挂钩机制才能捕获详细的异常信息。
第二种方法不仅需要 11.5 及更高版本,而且还要求您将应用程序编译为 .Net 目标类型之一(例如 WinForm)。鉴于您可能需要进行其他修改以支持编译为 WinForm,您可能会发现仅仅能够调用这个程序集就需要做太多的工作。另一方面,如果您正朝着 .Net 目标前进,那么您已经准备就绪。
我没有对 PowerBuilder 做过任何事情,但这是我们(非常成功地)在一个无法立即从 VB6 迁移的项目中遵循的技术。
1) 我们创建了一个带有 COM 引用的 shim/facade,以公开我们需要的 .NET 项目。(我们还指定了 GUID 的 using 属性,因此我们可以完全控制兼容性更改。)
2)我们使用内置对象处理(在您的情况下为 OleObject)在我们的 VB6 代码中引用了 COM 对象(就像您在 PowerBuilder 代码中一样)。
3) 随着项目的迁移(在我们的例子中是 C#),它们引用了底层的 .NET 类而不是 COM shim。(我们用过时的标签标记了垫片,以确保没有人意外使用它。)
4) 在迁移了对 shim 的所有引用后,我们删除了 shim。(我们实际上是分两个阶段完成的。在第一阶段,我们将 shim 保留在其中,但对其进行了修改以引发异常并记录有关调用的信息。这样我们就可以知道对它的任何调用在哪里确认没有问题后,在下一阶段拆除垫片。)
这对我们的好处是迁移可以增量发生。我们选择不直接公开底层 .NET 对象,因为它们仍然存在更改的风险,并且我们需要 COM 接口尽可能稳定。
升级到 PB.NET 肯定是可能的……但我不知道迁移会有多复杂。您可能会发现必要的时间会使迁移成为一个重大项目(这对我们来说肯定是)。
我们考虑过但因不适合我们需要而被拒绝的其他方法是:
将 .NET 组件包装在另一个应用程序(“服务”)中,并通过套接字通信与这些组件通信。
使用 .NET 框架向实用程序“发送”并通过(例如)基于文件的机制传输信息。
需要注意的事项包括:
链接两侧使用的线程模型。(我们一开始是因为系统的一部分运行 MTA 而不是 STA - 请参阅此问题以获取更多信息。)
从您的应用程序来看,.NET 端的异常会是什么样子。这可能是一个非常无用的“通用”错误,甚至可能出现在调用者而不是 .NET 代码中。我们在 .NET 端添加了日志记录,它在重新抛出异常之前提供了更详细的任何异常记录,并让调用者尽可能地处理事情。
我希望这有帮助。祝你好运!
我现在实际上面临着同样的问题。我们使用 PB 11.5,但此时我们无法将我们的应用程序移动到 .NET 目标,并且在本机 PB 应用程序中无法执行 .NET 的东西(PowerScript#...)。所以,我向我们当地的支持寻求建议,他们回答 Sybase 的建议是使用 PBNI:
CodeExchange的 Roy Kiesler 有一个很好的示例项目,名为 PB2DOTNET。将帮助您跳过前几个步骤(请注意,代码不是新的,您必须迁移本机 PB 和 PBNI 的东西)。
这种方法的缺点是它增加了您必须维护的中间级别。但是,PBNI 类应该只是 .NET 类的一个薄包装,这样您就可以在升级到 PB12 后轻松摆脱 PBNI 部分。