2010-11-09 52 views
0

我在C++和VB6中有一个COM对象,并且所有东西都使用Visual Studio 2003进行编译和打包.C++生成DLL和VB6 EXE,所以从我可以调用的遗留代码调用DLL等的EXE。将C++ vb6 COM对象转换成dot net

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

1)我可以编译C++和生成的DLL - (我认为是确定) 2)VB.Net没有按”没有选择生成COM/ActviveX了VB6,所以不知道 - 我试图生成Windows EXE和调用DLL,但它不起作用。我认为是因为它有一些COM调用。

那么什么是摆脱COM/ActiveX和提供某些东西的最佳解决方案?

用C++编译并在VB.net中加载引用?我试过这个但是DLL不加载.........

+0

亚历克斯你可能想打破这个问题,并提出有关重新编码单独的位到VB.net的多个问题。 – 2010-11-09 18:38:03

回答

1

你还没有澄清如果VB代码是一个进程外COM服务器,或者是一个客户端使用C++ inproc COM对象。

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

如果你的VB.Code是一个进程外的COM服务器,你必须用COMVisible属性标记你想要通过COM进行授权的类,然后使用RegAsm工具向COM注册你的程序集。

另一种替代方法是编译的C++代码为托管C++,并从VB代码作为标准管理组件参照的文它。这种方法的优点是你可以完全绕过COM互操作层并完全保留在托管的世界中,这有一定的完美优势。而另一方面,有两个缺点 - 一)你的C++代码将只能访问特定的客户端,除非你把它放在GAC,和b)编写托管C++西港岛线需要有点斜升的。我不认为第一个会影响到你,在你的情况这听起来是COM仅使用从VB6代码跨越到一个较低的水平C++的便捷方式。然而,第二个可能会给你一些麻烦。

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

如果确实如此,那么我的建议是将VB6代码重新编译为VB.Net(并且您可能必须对代码进行一些更改,因为这两个平台并非完全相同),以及其暴露在使用标记有ComVisible特性作为COM对象,并使用P/Invoke来消耗电流C++代码(这是相当类似的方式目前你的VB6代码消耗它)。不应该需要将C++重新编译为托管C++组件。

+0

唯一认为我知道的是,vb6使用私有声明函数x_ImageType Lib“xImage.dll”加载dll,该函数使用C++编译,其他应用程序调用这些VB6函数。我尝试了Tlbimp C++,但它没有工作消息是它不是一个有效的库 – Alex 2010-11-09 05:41:52

+0

这很可能意味着VB可执行文件是一个使用C++ COM类的客户端。 – 2010-11-09 05:44:34

+0

我认为你是对的,它正在消耗 – Alex 2010-11-09 05:47:38

1

好吧,你似乎有一个小小的误解。 .net是与COM/VB完全不同的环境。它们就是所谓的非托管代码,而.NET则是托管的。你可以通过一个叫做InterOp的调用(并且有很多类型的)。

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

.net不活动X也可以。你不能只是重新编译一个c + + dll(com或以其他方式到.net)。然而,C++的特殊版本称为托管C++,它在托管代码和非托管代码之间存在。

您有以下选择。

  1. 重新编码的VB程序,并使用COM互操作从vb.net访问现有的COM对象
  2. 重新编码VB程序和重新编码COM功能(或者托管C++或重新编码到VB.net)以完全。 net
  3. 保留VB程序并将COM功能(托管C++或重新编码为VB.net)重新编码为完全.net,并使用.net的功能公开COM接口。
  4. 独自离开
+0

我可以用C++重新编译C++吗?然后写一些在vb.net或c#到这个DLL?或者我需要重新编写整个C++程序? – Alex 2010-11-09 05:51:36

+0

没有Active X功能需要在MC++中获得托管C++包装器。 – 2010-11-09 06:06:47

+0

VB6可以通过VB.Net升级向导半自动升级到VB.Net。有第三方工具声称以非常高的精度自动将VB6升级到VB.Net。 – MarkJ 2010-11-10 09:55:06

1

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

您有两种选择。

  • 您可以使用P/Invoke直接从.Net调用C++ DLL。 C++不需要更改代码,您可以使用现有的DLL。您可以使用P/Invoke Interop Assistant自动生成C++头文件中的P/Invoke代码。
  • 如果你愿意改变C++,你也可以使用C++ Interop,这被认为不太繁琐的实现。
+0

我有零C++技能,所以我怎么知道C++ DLL是普通的而不是COM。在这种情况下,使用P/invoke – Alex 2010-11-09 21:36:54

+0

您在别处说过,VB6使用'Declare Function'加载C++ DLL,这意味着C++ DLL必须是普通的DLL而不是COM。你需要VB.Net中的一些P/Invoke声明。您可以(i)将VB6'Declare'转换为VB.Net'Declare',我认为您必须手动执行或(ii)找到C++函数声明,将其复制并粘贴到* P/Invoke Interop助理*,然后它会为您生成VB.Net声明或(iii)如果只有一个或两个'Declare'语句,您可以在这里发布它们,我们可能可以将它们转换为您:) – MarkJ 2010-11-10 09:52:47