1
votes

I'm writing a plugin implementing a 3rd-party interface in C++. I created an ATL project in MSVS, added an ATL Simple Object, then used the "Implement Interface" shortcut on that class. All of the interface methods got stubbed and it builds. I also added:

[assembly:System::Runtime::InteropServices::ComVisible(true)];

and have these running (successfully) after the build:

regsvr32.exe VWorksCPPATL.dll
regasm /codebase /tlb VWorksCPPATL.dll

However, when I open the DLL in oleview, I don't see any of the interface's methods exposed (aside from IUnknown) and the DLL doesn't get loaded by the container for the plugin.

When I open a working DLL that I wrote in C#, I see the interfaces that I've implemented and their methods listed under the coclass. (I had set the "register for COM interop" and "make assembly COM-visible" attributes on the project.)

When I open working DLLs that the vendor (creator of plugin container) wrote in C++, I see the exposed methods/interfaces in some, but not all, of the DLLs.

Do I need to manually modify my IDL file to expose these methods? Right now it shows (attributes omitted):

interface IPF400 : IDispatch{}
library VWorksCPPATLIB{
    coclass PF400{
        [default] interface IPF400;
    }
}

...Or am I likely having troubles for other reasons?

1
Do you see empty type library or no type library at all in COM/OLE Viewer? Do you see what you need in .TLB file produced among temporary build files?Roman R.
The temporary TLB and the embedded TLB are the same. All they contain are the IDispatch members (GetTypeInfoCount, etc.). Pasted here: gist.github.com/zbjornson/8805c2e85b3d70dd2248dd387fbcf231. I assume I need to modify the IDL file to say I'm implementing the other interfaces, but I would hope there's an automatic way to do that.ZachB
Looks good. IPF400 is there. Your IDL IPF400 is also empty, just what you see in the compiled TLB.Roman R.
@RomanR. do I need to manually add the methods of the interface that I've implemented to the IDL file then? I would have thought that the "implement interface" shortcut would do this for me, or that there's some other automatic way to generate it.ZachB
IDL's interface should not be empty. See this Q for sample IDL, see IQTAction::Run in particular. Not sure about automatic generation, but your IDL does have to have these definitions before you build the project.Roman R.

1 Answers

1
votes

Alright, I had to follow the instructions in this answer to export the TLB from the DLL that contains the interface that I'm implementing, then add importlib("....tlb") and interface IFooInterface to the IDL file manually (attributes omitted):

interface IPF400 : IDispatch{
};

library VWorksCPPATLLib
{
    importlib("stdole2.tlb");
    importlib("IWorksDriver.tlb"); // <-- Added

    coclass PF400
    {
        interface IControllerClient; // <-- Added
        [default] interface IPF400;
    };

};