Question

I have declared C++/CLI class as below

namespace testcominterface {

  [ComVisible(true)]
  [Guid("FFCA805F-8DAB-4AF8-A7B7-B488136E8177")]
  public interface class ITestInterface
  {
      public :
          void TestMethod();
  };


  [ComVisible(true)]
  [Guid("E65F4772-54B5-4105-83E5-DCED24ABC815")]
  [ClassInterface(ClassInterfaceType::AutoDual)]
  [ComDefaultInterface(ITestInterface::typeid)]       
  public ref class testCoClass : ITestInterface
  {
      public:
          virtual void TestMethod()
                {

                    Console::WriteLine("testCoClass::TestMethod : Test method");

                }
  };
 }

And I want to create the "testCoClass" through native C++ COM (by #import the TLB file and use CoCreateInstance) I always get an error "Class Not Registered". If I use "Regasm.exe" to register the assembly it works fine, but I don't want to register the assembly.

I have followed the steps in this blog post http://blogs.msdn.com/b/cheller/archive/2006/08/24/how-to-embed-a-manifest-in-an-assembly-let-me-count-the-ways.aspx to embedded manifest into the Assembly, but it didn't work. (Note that this method always works with C# assembly, but this is a C++/CLI assembly.

I appreciate any suggestions.

Was it helpful?

Solution

A COM server needs to be registered so that COM can find the DLL when a client program asks for it. Technically it can be avoided by giving the client program a manifest with reg-free COM entries, <clrClass> is required for COM servers that are written with managed code. Key point is that this manifest needs to be embedded in the client, not the server. Don't go there yet until you've got your COM server working properly.

One standard mistake is forgetting to use the /codebase option with Regasm.exe. Without it, the assembly needs to be strong-named and put in the GAC. This is not something you want to do on your dev machine. Another common mistake is using the wrong version of Regasm.exe. You'll need to pay attention to the bitness on a 64-bit machine. And pick the right one if you use VS2010 and use the GAC, .NET 4 has a different location for the GAC.

You ought to improve the attributes you use. A proper COM server only exposes the interfaces and hides the implementation. Use [InterfaceType(ComInterfaceType::InterfaceIsDual)] on the interface declaration and [ClassInterface(ClassInterfaceType::None)] on the class. You now also no longer need [ComDefaultInterface] and the type library dependency on mscorlib.tlb will be gone.

If you still have trouble then SysInternals' ProcMon utility can show you exactly where in the registry the client looked for your server and compare it against the actual registry locations that your server uses.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top