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:
- Create a C# console app project. I name it CSharpApp
- 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.
- (Removed, kept to keep numbering in answers correct.)
- Compile.
- 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...'
- In Program.cs, Main, create an InteropDemo class and call HelloWorld.
- Profit.
Thanks to the answers, I updated the question to reflect the combined solution.
Try following these steps:
- 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.
- Open Admin Command Prompt and register your COM DLL:
C:\Windows\SysWOW64\regsvr32.exe c:\full-path\ComLib.Interop.dll
- 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.
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".