How to create a HelloWorld COM Interop in Visual S

2019-01-12 00:48发布

问题:

First off, I am new to COM, and currently quite confused. I've read a lot of documentation on COM on MSDN and the general web, but a lot of it seems outdated and overly complex.

Here's what I believe to be necessary to get it to work. It doesn't yet, so I am sure I am missing something, but by giving my recipe, I hope someone can spot the problem:

  1. Create a C# console app project. I name it CSharpApp
  2. Create a C++ ATL project. I call it ComLib.Interop.
    • Add class (template: ATL Simple Object), which I call "InteropDemo"
    • In class view, right-click IInteropDemo and add a method HelloWorld.
  3. (Removed, kept to keep numbering in answers correct.)
  4. Compile.
  5. Add reference to ComLib.Interop.dll to CSharpApp.
    • Call regsrv32.exe on the compiled COM dll, then select the DLL in the COM tab in 'Add references...'
  6. In Program.cs, Main, create an InteropDemo class and call HelloWorld.
  7. Profit.

Thanks to the answers, I updated the question to reflect the combined solution.

回答1:

Try following these steps:

  1. Make sure both projects, unmanaged C++ and managed C# have the same bitness, either x86 or x64. Let's say it's x86, for clarity.
  2. Open Admin Command Prompt and register your COM DLL: C:\Windows\SysWOW64\regsvr32.exe c:\full-path\ComLib.Interop.dll
  3. Run Visual Studio as Admin. Do steps 1,2,4,5,6. Don't do 3.

See if you get to 7. I think that should work.

Note you only need the registration on the Development machine. Isolated COM should work everywhere else.



回答2:

You probably went wrong at step #2, given that you didn't get a build error. The wizard gives you more than one choice for the kind of class you add. The default choice is "C++ class", you need to pick ATL + "ATL Simple Object" instead.

The Class View window now shows two types getting added, the IInteropDemo interface and the CInteropDemo class that implements the interface. You next right-click the interface type (not the class) and use "Add Method". You can now also take a look at the IDL file in the project, it should resemble this:

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;
    };
};

That's enough to get it built. Which ought to fail on any modern Windows version, UAC prevents the COM server getting registered. Which requires step #0: Start Visual Studio by right-clicking the shortcut and selecting "Run as Administrator".