leiflundgren
leiflundgren

Reputation: 2966

Create each COM-instance in it's own exe-container

Is there possible to create a COM-instance in it's own, dedicated, host-process?

I guess some background is needed.

We have an end-user client which has it's central logical components inside an singleton-COM object. (Not propper singleton, but it uses global variables internally, so it would fail.) So that there should be only one instance per exe-file. Convenient while making the client.

However, I should now make a "client-simulator" to test the server-side. I therefore which to make 20 instances of the client-component. If I could make each instance instanciate in its own exe-host, then the singleton-issue would be handled.

Regards Leif

Upvotes: 3

Views: 2162

Answers (3)

Jim Gomes
Jim Gomes

Reputation: 824

I have been struggling with this problem for a few days. I finally found a solution that works. My COM object is written using ATL, so my code snippet will be geared toward that, but the technical solution should be clear. It all hinges on how the class objects are registered. The REGCLS_SINGLEUSE flag is the key. I now have separate processes for each object instance.

In the ATL module, override the RegisterClassObjects() function as follows:

HRESULT RegisterClassObjects(DWORD dwClsContext, DWORD dwFlags) throw()
{
    return base::RegisterClassObjects(CLSCTX_LOCAL_SERVER, REGCLS_SUSPENDED | REGCLS_SINGLEUSE);
}

From MSDN regarding REGCLS_SINGLEUSE:

REGCLS_SINGLEUSE

After an application is connected to a class object with CoGetClassObject, the class object is removed from public view so that no other applications can connect to it. This value is commonly used for single document interface (SDI) applications. Specifying this value does not affect the responsibility of the object application to call CoRevokeClassObject; it must always call CoRevokeClassObject when it is finished with an object class.

My theory is that because the registration was removed from public view, it causes a new process to be created for the subsequent instantiations.

Upvotes: 3

Kim Gräsman
Kim Gräsman

Reputation: 7596

This other question mentioned a description of how to use DLLHost as a surrogate process: http://support.microsoft.com/kb/198891

I've never tried this myself, and I don't know off-hand if you can specify flags for the factories (which control if surrogates can be reused for multiple objects), but maybe you can tweak that via DCOMCNFG or OLEVIEW.

Upvotes: 2

Cygon
Cygon

Reputation: 9620

My COM days are long gone, but as far as I remember, there's no built-in way to do that.

It might be easier to rewrite your code so it supports multiple instances than to go the one-process-per-instance route with COM, but here's what you could do:

  • Use thread-local storage for your global variables and write another CoClass, where each instance owns its own thread through which accesses to the class with the global variables are marshaled. This would at least allow you to avoid the performance impact of DCOM.

  • Write your own out-of-process exe server (similar to windows' DllHost.exe) to host your COM instances. This requires IPC (Inter-Process Communication), so you either have to code something yourself that marshals calls to the external process or use DCOM (presuming your COM object implements IDispatch)

Upvotes: 2

Related Questions