如何在Visual Studio 2012中创建一个HelloWorld COM互操作

5
首先,我对COM还是比较陌生的,目前还很困惑。我已经在MSDN和一些网站上阅读了许多有关COM的文档,但其中许多看起来都已经过时且过于复杂。
以下是我认为需要完成此工作的步骤。它还没有起作用,所以我肯定缺少某些内容,但是通过提供我的步骤清单,我希望有人能找到问题所在:
1. 创建C#控制台应用程序项目。我把它命名为CSharpApp 2. 创建一个C++ ATL项目。我称其为ComLib.Interop。 - 添加一个类(模板:ATL简单对象),我将其称为“InteropDemo”。 - 在类视图中,右键单击IInteropDemo并添加HelloWorld方法。 3. (已删除,保留以确保答案中编号正确)。 4. 编译代码。 5. 将ComLib.Interop.dll引用添加到CSharpApp。 - 在编译后的COM dll上调用regsrv32.exe,然后在“添加引用…”中的COM选项卡中选择DLL。 6. 在Program.cs中的Main方法中创建一个InteropDemo类并调用HelloWorld方法。 7. 成功!
感谢回答,我更新了问题以反映综合解决方案。

我认为你不需要第三步和第四步。试着不用它们。 - noseratio - open to work
你可以说COM本身已经过时且过于复杂,因此它实际上已经不再被开发。如果你想认真地用C++开发COM服务器/对象,我建议你阅读唐·博克斯(Don Box)的《Essential COM》一书。唐曾是90年代末和21世纪初的COM大师,在他转而致力于第一个版本的WCF之前。这本书价值连城。 - simon at rcl
@Noseratio 不起作用,我得到了这个错误。然而,在ComLib.Interop.dll上手动调用tlbimp可以工作,我可以添加tlbimp生成的ComLib.InteropLib.dll。但是,然后我又遇到了注册的原始问题。已更新问题。 - Wilbert
2个回答

3
您可能在第二步出错了,因为您没有收到构建错误。向导为您提供了多个添加类的选项。默认选择是 "C++类",您需要选择 ATL + "ATL简单对象"。
类视图窗口现在显示正在添加两种类型,IInteropDemo接口和实现该接口的CInteropDemo类。接下来,您右键单击接口类型(而不是类),并使用 "添加方法"。您现在也可以查看项目中的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函数。 - Wilbert
我还检查了.idl文件,HelloWorld方法已添加到接口中。 - Wilbert
谢谢。我在这里添加了一个后续问题(http://stackoverflow.com/q/21335520/1591992)。 - Wilbert

3
请尝试按照以下步骤操作:
  1. 确保非托管C++和托管C#项目的位数相同,可以是x86或x64。为了清楚起见,假设它是x86。
  2. 管理员身份打开命令提示符,并注册COM DLL:C:\Windows\SysWOW64\regsvr32.exe c:\full-path\ComLib.Interop.dll
  3. 管理员身份运行Visual Studio。执行步骤1、2、4、5、6,不要执行第3步。

看看是否能进入第7步。我想应该会起作用。

请注意,您只需要在开发机上进行注册。隔离的COM应该在其他地方工作。


它起作用了:我可以在我的开发机上调用已注册的COM dll上的HelloWorld。但是如果我打开隔离,它会出现构建错误:问题隔离COM引用'ComLibInteropLib':未检测到此组件的已注册类。 - Wilbert
@Wilbert,错误还是警告?你确定两个项目都是x86,.NET也是吗?你不能使用“AnyCPU”。 - noseratio - open to work
两个工程都是x64的(我从开始就使用了x64,并且使用System32\regsrv32.exe注册了dll,而不是wow64)。我可以使用已注册的dll运行我的CSharpApp.exe,并且它可以从com dll方法打印出正确的hello world字符串。 - Wilbert
此时,我已经没有更多的想法了,但请查看这个链接 - noseratio - open to work
谢谢。我在这里添加了一个后续问题(http://stackoverflow.com/q/21335520/1591992)。 - Wilbert

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接