问题
I have a 32-bit ATL COM component without a type library. It has a class factory for one given class that implements several interfaces.
When I use it as an in-proc server, everything works fine - the client side invokes CoCreateInstance(), the object is instantiated and QueryInterface() retrieves a pointer to a requested interface. But when I put the component into COM+ I no longer can instantiate the class - CoCreateInstance() now returns E_NOINTERFACE.
I believe the problem is that COM+ can't perform marshaling because of absence of type library - it has no idea how to do it. Do I need to generate and register a type library to resolve this or is there any other way?
回答1:
Urk. I would recommend asking on microsoft.public.vc.atl as I think you will find more experts there. I think (though I'm not an expert) the issue has less to do with COM+ than the issue of registered proxy/stubs. (In other words, even if you wrote your own COM client to access your component out-of-process, you would probably run into the same issue) If you have standard Automation-compatible interfaces, then Windows knows how to marshal your objects just fine. But otherwise it is confused.
Without a type library, you either need to register proxy/stubs, or need to implement IMarshal yourself to handle custom marshaling. (or there's also this "handler marshaling" thing that I don't understand)
Your comment about why you don't have a type library (implementing an interface already defined by Microsoft, but one which doesn't have a typelib) raises a red flag with me. Can you provide more details? If it's something in a .DLL or .EXE, but the type information is inside the library itself (rather than an external .TLB file) it's probably possible to extract the right information to make everything work, I'm just not familiar with the process.
(For the record, I've left ATL/COM programming in favor of Java, so although I can let you know what I remember in the past, I don't use the tools now and it would be difficult for me to get back into them to provide any more help. But the folks on the microsoft.public.vc.atl are pretty smart.)
回答2:
Typelibs are one way to support marshalling, proxy/stub DLLs (genereated from the IDL) are another. In both cases, however, you'll need the IDL in the first place.
If Microsoft does not provide a typelib/proxy DLL or IDL for this interface, odds are that there is a reason for this: Maybe the interface uses non-marshalable data structures, requires function pointers to be passed as method parameter or things like this? If this is the case, there is just no way to make this interface work for DCOM.
Maybe you can reconstruct the IDL, but quite possibly, it just will not be feasible. Then your last fallback could be to use custom or handler marshalling, but that's probably not worth the effort. That said, I'd recommend considering other routes that does not involve using interfaces for DCOM that were not designed to be used for DCOM.
回答3:
For an COM interface to be marshallable using Microsoft's default marshaller, the interface has to have either the DUAL or the OLEAUTOMATION property defined in its header.
If there are arguments for the methods defined that are interface pointers, the same requirement extends to those interfaces.
Plus the interface name must be present in the LIBRARY section of the IDL defining it. This also extends to other referenced interfaces.
If these conditions are not met, the interface won't be marshallable.
来源:https://stackoverflow.com/questions/852497/what-is-required-to-enable-marshaling-for-a-com-interface