【问题标题】:Converting c++ vb6 COM object into dot net将 c++ vb6 COM 对象转换为点网
【发布时间】:2011-05-07 01:23:31
【问题描述】:

我有一个 C++ 和 VB6 中的 COM 对象,所有内容都是使用 Visual Studio 2003 编译和打包的。C++ 生成 DLL,VB6 生成 EXE,所以从遗留代码中我可以调用调用 DLL 的 EXE 等等开。

我需要将这些迁移到 Visual Studio 2008。但是,我有一些问题

1) 我可以编译 C++ 并生成 DLL - (我认为还可以) 2) VB.Net 不再有生成 COM/ActviveX 作为 VB6 的选项,所以不知道 - 我试图生成windows exe并调用dll,但它不起作用。我想是因为它有一些 COM 调用。

那么,摆脱 COM/ActiveX 并交付某些东西的最佳解决方案是什么?

在 C++ 中编译并在 VB.net 中加载添加引用?我试过这个,但DLL没有加载............

【问题讨论】:

  • Alex 您可能想将问题分解并提出多个关于将单独的位重新编码到 VB.net 中的问题。

标签: c++ vb.net com dll vb6-migration


【解决方案1】:

您尚未阐明 VB 代码是进程外 COM 服务器,还是使用 C++ inproc COM 对象的客户端。

如果 VB 代码是客户端,您可以将其构建为 VB.Net 可执行文件,使用对 coclass 的 COM 引用,或者如果您不希望在构建期间注册 C++ 对象,您可以可以使用类型库上的 TlbImp 工具生成托管互操作程序集以从 VB.Net 代码中引用。

如果您的 VB.Code 是进程外 COM 服务器,您必须使用 COMVisible 属性标记您希望通过 COM 获得信任的类,然后使用 RegAsm 工具向 COM 注册您的程序集。

另一种选择是将 C++ 代码编译为托管 C++,并将其从 VB 代码中引用为标准托管程序集。这种方法的优点是您将完全绕过 COM 互操作层并完全留在托管世界中,这具有一定的完美优势。另一方面,有两个缺点 - a) 您的 C++ 代码只能由该特定客户端访问,除非您将其放在 GAC 中,以及 b) 编写托管 C++ 将需要一些加速。我认为第一个不会影响您,因为在您的场景中,听起来 COM 仅用作从 VB6 代码交叉到较低级别 C++ 的便捷方式。但是,第二个可能会给您带来一些麻烦。

更新:根据您的评论更新,您似乎有一个直接从 VB 代码调用的 C++ 代码,而该代码又通过 COM 从其他客户端调用。

如果确实如此,那么我的建议是将 VB6 代码重新编译为 VB.Net(您可能必须对代码进行一些更改,因为这两个平台并不完全相同),并公开它使用 COMVisible 作为 COM 对象,并使用 P/Invoke 来使用当前的 C++ 代码(这与当前您的 VB6 代码使用它的方式非常相似)。不需要将 C++ 重新编译为托管 C++ 组件。

【讨论】:

  • 我唯一知道的是vb6使用使用c ++编译的私有声明函数x_ImageType Lib“xImage.dll”加载dll,其他应用程序调用这些VB6函数。我试图 Tlbimp C++,但它没有工作,消息是它不是一个有效的库
  • 这很可能意味着 VB 可执行文件是一个使用 C++ COM 类的客户端。
【解决方案2】:

好吧,你似乎有点误会了。 .net 是与 COM/VB 完全不同的环境。它们是所谓的非托管代码,而 .net 是托管的。您可以使用称为 InterOp 的东西从一个呼叫到另一个呼叫(这种类型有很多种)。

第一个 vb6 - 要将其转换为 .net,您需要重新编码应用程序。 .net 不是 VB。虽然语言相似。

.net 也不是活动 X。您不能只重新编译 c++ dll(com 或其他方式到 .net)。但是,有一个特殊版本的 C++,称为托管 C++,介于托管代码和非托管代码之间。

您有以下选择。

  1. 重新编码 VB 程序并使用 vb.net 中的 COM InterOp 访问现有的 COM 对象
  2. 重新编码 VB 程序并将 COM 功能(托管 C++ 或重新编码为 VB.net)重新编码为完全 .net
  3. 离开 VB 程序并将 COM 功能重新编码(托管 C++ 或重新编码为 VB.net)以完全 .net 并使用 .net 的能力来公开 COM 接口。
  4. 别管了

【讨论】:

  • 我可以在 C++ 托管中重新编译 C++ 吗?然后用vb.net或c#写一些到这个DLL?还是我需要重新编码整个 c++ 程序?
  • 没有 Active X 功能需要在 MC++ 中获得托管 C++ 包装器。
  • VB6 可以通过 VB.Net 升级向导半自动升级到 VB.Net。有第三方工具声称可以以非常高的准确度自动将 VB6 升级到 VB.Net。
【解决方案3】:

听起来你的 C++ DLL 是一个普通的 DLL(不是 COM),VB6 可以使用 Declare 语句访问它。

你有两个选择。

  • 您可以使用 P/Invoke 从 .Net 直接调用 C++ DLL。无需对 C++ 进行代码更改,您可以使用现有的 DLL。您可以使用 P/Invoke Interop Assistant 从 C++ 的标头中自动生成 P/Invoke 代码。
  • 如果你愿意改变 C++,你也可以使用 C++ Interop,据说实现起来不那么繁琐。

【讨论】:

  • 我的c++技能为零,我怎么知道C++ DLL是不是普通的而不是COM。在这种情况下使用 P/invoke
  • 您在别处说过,VB6 使用Declare Function 加载C++ DLL,这意味着C++ DLL 必须是普通DLL 而不是COM DLL。您需要在 VB.Net 中进行一些 P/Invoke 声明。您可以 (i) 将 VB6 Declare 转换为 VB.Net Declare,我认为您必须手动执行此操作,或者 (ii) 找到 C++ 函数声明,将其复制并粘贴到 P/调用 Interop Assistant,然后它将为您生成 VB.Net 声明或 (iii) 如果只有一两个 Declare 语句,您可以在此处发布它们,我们也许可以为您转换它们:)
猜你喜欢
  • 1970-01-01
  • 2010-12-07
  • 2012-04-03
  • 2011-10-29
  • 1970-01-01
  • 2012-08-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多