Question

I'm relatively new in COM, so appologies if this is a stupid question. I'm having a bunch of COM interfaces compiled into a type library A. This type library is a resource in one of the DLLs (a.dll) in my solution. In a separate type library (B) that goes into a separate DLL (b.dll) I would like to define a coclass that implements an interface from type library A. See the IDL code below as a simplified example of what I have in mind:

import "oaidl.idl";
import "ocidl.idl";

// Import IMyInterface, which is part of MyLibA.tlb
import "MyInterface.idl";

[
    uuid(E80492A8-1E8C-4ABF-B4DE-9C252C445AFE),
    version(1.0),
    helpstring("MyLibB Type Library")
]
library MyLibB
{
    importlib("stdole32.tlb");
    importlib("stdole2.tlb");
    importlib("MyLibA.tlb); 

    [
        uuid(25E3CD5E-FA06-4845-BE3E-F260985AFB20),
        helpstring("My CoClass")
    ]
    coclass MyCoClass
    {
         [default] interface IMyInterface;
    };
};

I can compile the above ok, but when I open the tlb file generated by MIDL in oleview, I get an error message TYPE_E_CANTLOADLIBRARY. I'm beginning to suspect what I want to do is not possible. My experimentation so far suggests that type libraries need to contain all the interfaces that a coclass implements along with the coclass definition itself. Is this true?

If I remove the importlib("MyLibA.tlb); statement, I can view the compiled tlb file in oleview without errors, but MyLibB.tlb then also contains the definition of the IMyInterface interface, i.e. the interface is defined twice in both type libraries. I don't want this because in my application I load both a.dll and b.dll using registration-free COM. In this scenario, the activation context generation fails when it encounters the same interface definition in more than one type library.

Any suggestions how I can achieve the desired interface and coclass separation in separate type libraries?

Était-ce utile?

La solution

When OLE/COM viewer shows the TYPE_E_CANTLOADLIBRARY this typically means that another TLB which is referenced from the one which is being opened is not properly registered.

The fix is to register the dependency TLB (in this case MyLibA.tlb) with a tool like regtlb or regtlib or alternative, depending on your system.

As the question is given in the context of registration-free COM, you should be aware of possible issue with regard to marshaling of the interface instances. Typically, TLBs must be registered in order to use standard marshaller. Otherwise, you must make sure to properly declare marshaling info in your manifests, as mentioned here

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top