You need to write a function called DllGetClassObject and export it. That function is responsible for allocating a "class factory", which you also have to write, and which is in turn capable of allocating instances of your COM object. It has to implement IClassFactory.
It's not too hard to do. The alternative is to use ATL (see xhantt's answer) which in theory does this for you, but in practice it's a real mess. Somehow it manages to encapsulate the complexity of COM inside an abstraction layer that is even more complicated. Good luck trying to move an object between DLLs for example.
But you could run the ATL wizard just to see an example of how to declare DllGetClassObject
. Implementing IClassFactory
is very easy - just one method that news-up an object.
Then you need to register your DLL - i.e. put keys into the registry. The regsvr32
tool cannot do this without further help from you. You have to write and export another function called DllRegisterServer, which does all the hard work. All that regsvr32
does is load the DLL, look up DllRegisterServer
and call it.
Again, ATL has a way of implementing this for you, but it does it by reading a kind of script full of registry modification instructions, stored in an .rgs file that gets embedded into your DLL's resources. If you accidentally put any kind of syntax error into this file, the registration fails silently.
So again, you may actually find it simpler to write a few lines of code to tweak the registry yourself. Here are the details.
If you used C# instead, you wouldn't have any of these problems. Everything is encapsulated very cleanly. It actually works much better than C++ as a tool for developing COM objects.