【问题标题】:How to create a HelloWorld COM Interop in Visual Studio 2012如何在 Visual Studio 2012 中创建 HelloWorld COM 互操作
【发布时间】:2014-02-15 10:19:52
【问题描述】:

首先,我是 COM 新手,目前很困惑。我在 MSDN 和一般网络上阅读了很多关于 COM 的文档,但其中很多似乎已经过时且过于复杂。

这是我认为让它发挥作用所必需的。还没有,所以我确定我遗漏了一些东西,但是通过提供我的食谱,我希望有人能发现问题:

  1. 创建一个 C# 控制台应用程序项目。我把它命名为 CSharpApp
  2. 创建一个 C++ ATL 项目。我称之为 ComLib.Interop。
    • 添加类(模板:ATL Simple Object),我称之为“InteropDemo”
    • 在类视图中,右键单击 IInteropDemo 并添加方法 HelloWorld。
  3. (已删除,保留以保持答案中的编号正确。)
  4. 编译。
  5. 将 ComLib.Interop.dll 的引用添加到 CSharpApp。
    • 在编译好的 COM dll 上调用 regsrv32.exe,然后在“添加引用...”的 COM 选项卡中选择 DLL
  6. 在 Program.cs 的 Main 中,创建一个 InteropDemo 类并调用 HelloWorld。
  7. 利润。

感谢答案,我更新了问题以反映综合解决方案。

【问题讨论】:

  • 我认为您不需要步骤 3、4。尝试不使用它们。
  • 你可以说COM本身已经过时并且过于复杂,因此它不再真正被开发了。如果您对使用 C++ 开发 COM 服务器/对象很认真,那么我建议您阅读 Don Box 的《Essential COM》一书。在 90 年代末和 2000 年代初,Don 是 COM 大师,之后他开始着手开发 WCF 的第一个版本。价值不菲。
  • @Noseratio 不起作用,我得到this error。但是,在 ComLib.Interop.dll 上手动调用 tlbimp 是可行的,我可以添加 tlbimp 生成的 ComLib.InteropLib.dll。但后来我又遇到了最初的注册问题。更新了问题。

标签: c++ .net com com-interop


【解决方案1】:

尝试以下步骤:

  1. 确保两个项目(非托管 C++ 和托管 C#)具有相同的位数(x86 或 x64)。为了清楚起见,假设它是 x86。
  2. 打开 Admin 命令提示符并注册您的 COM DLL:C:\Windows\SysWOW64\regsvr32.exe c:\full-path\ComLib.Interop.dll
  3. Admin 身份运行 Visual Studio。执行步骤 1、2、4、5、6。不要做3。

看看你能不能达到 7。我认为这应该可行。

请注意,您只需要在开发机器上进行注册。独立的 COM 应该可以在其他任何地方工作。

【讨论】:

  • 成功了:我可以在注册的 COM dll 上调用我的开发机器上的 HelloWorld。但是如果我打开隔离,它会得到一个构建错误:Problem isolating COM reference 'ComLibInteropLib': No registered classes were detected for this component.
  • @Wilbert,错误还是警告?您确定这两个项目也是 x86、.NET 吗?你不能使用AnyCPU
  • 两个项目都是 x64 的(我从 x64 开始就使用它,并使用 System32\regsrv32.exe 而不是 wow64 注册 dll)。我可以使用注册的 dll 执行我的 CSharpApp.exe,它会从 com dll 方法中打印出正确的 hello world 字符串。
  • 到此,我也没有什么想法了,还是看看this吧。
  • 谢谢。我添加了一个后续问题here
【解决方案2】:

您可能在第 2 步出错了,因为您没有收到构建错误。向导为您添加的类的种类提供了多个选择。默认选择“C++ 类”,您需要选择 ATL +“ATL 简单对象”。

类视图窗口现在显示两个 类型正在添加,IInteropDemo 接口和实现该接口的 CInteropDemo 类。接下来右键单击 interface 类型(不是类)并使用“添加方法”。您现在还可以查看项目中的 IDL 文件,它应该类似于:

import "oaidl.idl";
import "ocidl.idl";

[
    object,
    uuid(CBA0D899-2F4C-4F1D-A935-C80CB981C153),
    dual,
    nonextensible,
    pointer_default(unique)
]
interface IInteropDemo : IDispatch{
    [id(1)] HRESULT Method();
};
[
    uuid(ED14ACED-4FF9-4144-B302-CC48C481F28B),
    version(1.0),
]
library ATLProject4Lib
{
    importlib("stdole2.tlb");
    [
        uuid(8543642F-9927-451C-9784-6A7774418299)      
    ]
    coclass InteropDemo
    {
        [default] interface IInteropDemo;
    };
};

这足以构建它。在任何现代 Windows 版本上都应该失败,UAC 会阻止 COM 服务器注册。这需要第 0 步:通过右键单击快捷方式并选择“以管理员身份运行”来启动 Visual Studio。

【讨论】:

  • 我确实做到了这一点,并基于 ATL 简单对象生成了一个类,并且我确实将方法添加到了接口中。如果我单击其中一个 IInteropDemo 界面(带有悬停文本“struct IInterfaceDemo”的界面),我会在下面的小框中看到 HellowWorld 函数。
  • 我还检查了.idl文件,HelloWorld方法添加到了界面中。
  • 谢谢。我添加了一个后续问题here
猜你喜欢
  • 2012-10-01
  • 2018-05-10
  • 2016-03-07
  • 2012-02-27
  • 1970-01-01
  • 2011-01-27
  • 2011-02-14
  • 2022-01-13
相关资源
最近更新 更多