Click here to Skip to main content
13,898,386 members
Click here to Skip to main content
Add your own
alternative version

Stats

15.8K views
782 downloads
29 bookmarked
Posted 9 Oct 2015
Licenced CPOL

Using COM Without Registration

, 9 Oct 2015
Rate this:
Please Sign up or sign in to vote.
A small class for using COM DLL modules without registering them

Introduction

This tip describes how to use a COM DLL without registering it. You will find a small class here which you can use in your projects.

C++ developers who have heard about COM but don't know it, might think "Nuh, all the stuff I have to implement - too complicated". But when it comes to modularization, COM provides an excellent mechanism to deal with components imported from DLLs.

If you are one of these developers, you should probably read Alex Blekhman's article about how to export classes from a DLL. It leads nicely to the concept of COM - exporting interfaces.

When you reached the point where you think that using interfaces to export classes is really a good idea, you might notice that COM actually provides you with all the mechanisms you need to manage the lifetime of your objects and your modules and to create instances. You might also notice that by exporting a few functions from your DLL, you can create a COM DLL that you can easily use from your application.

One downside is there though: Normally a COM DLL has to be registered so the OS can load it when you say "create an instance of this or that class". You might not want that, maybe because you don't want your application to require any installation, maybe you don't want that your DLL can be used (easily) by other applications. So that's what this tip is about: Using components from your DLLs without registering.

Using the Code

Usually, when you want to instantiate a COM object, you would use:

HRESULT CoCreateInstance(
  REFCLSID  rclsid,
  LPUNKNOWN pUnkOuter,
  DWORD     dwClsContext,
  REFIID    riid,
  LPVOID    *ppv
);

COM will lookup the CLSID in the registry, see which module provides this class, load the module (DLL) and ask the module to create that instance.

So if you want to instantiate a class that is not registered, you have to do all these steps yourself. That's what ComLibrary is for. It has the following interface:

class ComLibrary
{
  HRESULT Load(LPOLESTR szDllName);
  HRESULT Unload(BOOL bForce = FALSE);

  HRESULT GetClassObject(REFCLSID aClsid, REFIID aIid, LPVOID FAR* ppv);
  HRESULT CanUnloadNow();

  template<class Iface> HRESULT CreateInstance(
      REFCLSID aClsid,
      Iface** aRetPtrPtr,
      IUnknown* aUnknownOuter = nullptr);
};

Using it is straight forward, as you might guess from the interface. For each module you are planning to use, provide an instance of ComLibrary. It has to live as long as you are using that module:

class MyApp
{
...
  private:
    ComLibrary  mMathModule;
}

Load the library on startup. Note that the path has to be absolute and can't be a network path to prevent security issues with loading DLLs from unexpected sources:

HRESULT MyApp::Init()
{
  HRESULT hr = mMathModule.LoadModule(GetAppPath() + 'mathmodule.dll');
  if (FAILED(hr))
  {
    // error handling
  }
}

And then, instead of calling CoCreateInstance(...), do:

...
IVector * pVector = nullptr;
HRESULT hr = mMathModule.CreateInstance(CLSID_Vector, &pVector);
// error checking etc.

You will still have to specify a CLSID of course. When you create a COM DLL, you probably use MIDL to define your interfaces. If so, the MIDL compiler will create a _h.h and a _i.c file. Include them in your application, and you have everything you need to use your interfaces and CLSIDs.

When you are done using your instances, just release them as usual. If you feel you are done using your mathmodule, you can call UnloadModule(...). This will check if there are still outstanding references to that module (via DllCanUnloadNow()) and unload the DLL if there are no more instances in use, or if you specify bForce. Usually, you would do this before exiting your application.

A few notices about the module DLLs: When you create a ATL COM DLL using the assistant from VS, you end up with a DLL that can be registered. If you don't want that, you can simply remove some stuff. This also helps to keep things clean. So what you should do is:

  • Remove some resources, namely the .rgs files.
  • Check your CAtlDllModule class (usually in dllmain.h) and remove the macro DECLARE_REGISTRY_APPID_RESOURCEID.
  • In your CAtlDllModule implementation file, remove the DllRegisterServer(), DllUnregisterServer and DllInstall functions. Remove them also from your .def file.
  • In all your COM classes, replace the macro DECLARE_REGISTRY_RESOURCEID(...) with DECLARE_NO_REGISTRY()

Sample Code

The sample code uses ATL, although the ComLibrary class doesn't, you can use it in plain COM.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

imagiro
Software Developer
Germany Germany
Born in 1968 I do programming since over 25 years now. I started with Basic on a ZX81 and with hacking hexcodes in a Microprofessor before I switched to C++ and other languages.

Since more than 10 years I work as a professional software developer, currently for Salsitasoft in Prague.

You may also be interested in...

Pro
Pro

Comments and Discussions

 
Questiondll .NET Pin
Joxemi11-Feb-19 5:33
memberJoxemi11-Feb-19 5:33 
Hi,

I've got a dll .NET and I haven't got any _i.c nor _i.h. How can I use this module to call my dll .NET? Is it posible?
Or ... how can I generate this files (_i.h and _h.c) from my dll .NET?

Many thanks in advance
Questionusing ComLibrary class with C# Com DLL Pin
ShameRox28-Jul-17 2:53
memberShameRox28-Jul-17 2:53 
QuestionSecond PathIsNewworkPathW needs changing to PathIsRelative? Pin
ehaerim28-Jan-17 19:02
memberehaerim28-Jan-17 19:02 
QuestionCOM definition on manifest Pin
nbarbosa9-Oct-15 11:27
membernbarbosa9-Oct-15 11:27 
AnswerRe: COM definition on manifest Pin
imagiro9-Oct-15 20:21
memberimagiro9-Oct-15 20:21 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web04 | 2.8.190306.1 | Last Updated 9 Oct 2015
Article Copyright 2015 by imagiro
Everything else Copyright © CodeProject, 1999-2019
Layout: fixed | fluid