Why do I get a QueryInterface(IID_IMarshal) and then nothing?

A common problem when trying to get your new COM object off the ground is that you can't seem to be able to get it created. The object comes out of the class factory, and it gets a QueryInterface for IMarshal, and then nothing. What's going on?

This is a sure sign that you didn't register your CLSID properly; most likely you forgot to set your threading model properly. (And if you fail to specify a threading model at all, then you get the dreaded "main" threading model.)

If somebody tries to create a COM object from a thread whose model is incompatible with the threading model of the COM object, then a whole bunch of marshalling stuff kicks in. And if the marshalling stuff isn't there, then COM can't use your object.

There is a long and very technical article in MSDN on COM threading models which has lots of scary-looking diagrams and tables. In particular, the second scary table in the "In-process servers: (almost) totally dependent on their clients" chapter lists all the combinations of thread models with object threading models, and what COM tries to do in each case.

In particular, notice that if you have a (mistakenly marked) "main"-threaded object and somebody on any thread other than the main thread tries to create it, marshalling will try to kick in.

So watch those threading models. The failure modes when you get them wrong are quite baffling.

Comments (8)
  1. Jack Mathews says:

    COM sometimes makes me want to cry.

  2. Lonnie McCullough says:

    I have a question I have always wondered about. Say you have several objects that all aggregate the free threaded marshaler (and of course abide by the rules of doing so…no non free threded object references being held and whatnot). Is there any benefit to making the class object for those objects also aggregate the free threaded marshaler? Is this even safe (don’t see why it wouldn’t be on first inspection)?

  3. Raymond Chen says:

    Sorry, I’m not an expert on COM marshalling. Maybe there’s a COM blogger you can ask.

  4. Mike Dunn says:

    I always had the impression that you had to implement IMarshal only if you wanted to use your own custom marshaling. If you didn’t respond to a QI for IMarshal, you would get the default marshaling from COM (using the type library, for instance).

  5. Raymond Chen says:

    This assumes that the interface COM is trying to marshal has a registered type library in the first place.

  6. Lonnie McCullough says:

    Unfortunately COM is so 2001 and your the only guy I know of that has even mentioned an IID in the past couple weeks.

  7. Anonymous says:

    I had this problem with some CE ActiveX controls originally developed for Pocket PC, when running them on a custom platform (PDT7200, if memory serves)….

  8. It’s the other half of the missing IMarshal.

Comments are closed.