Re: help creating a plugin

"Peter Millard" <me-STcBuFROdrv2eFz/[email protected]> Fri, 17 Dec 2004 14:32:55 -0700
Newsgroups gmane.network.jabber.exodus.devel
Message-ID <00f201c4e47f$f8cf6f20$e201020a@pmillard2k>
Clarke, Trevor wrote:
> I'm trying to create a plugin for Exodus and I'm having some trouble. As
> a test, I'm only really implementing Configure and it just pops a
> message box. I've added boilerplate code for the DLL functions, etc.
> (I'm using VC++ BTW) I can load the DLL with regsrv32 so I know that
> much is working. When I put the compiled plugin in the plugins
> directory, I'm getting noting. It does not show up on the
> Options->Plugins list and if I start it in a debugger and put
> breakpoints in the DLL initialization code it is not reaching this. How
> does exodus determine which files to load? Is there some trick to
> getting it to recognize my plugin? (Do I need to export some special
> static function or something?) Any help is appreciated. BTW, the
> boilerplate code is pretty standard...just set up reference counting
> where needed, does the COM book keeping, etc. so I won't bother
> attaching it unless requested.

I'm no VC++ expert... but there is some stuff going on to determine whether or
not to show the plugin. We scan the directory for .dll's and for each one,
attempt to load the type library from inside the DLL. Perhaps VC++ isn't
automatically putting in the TLB into the DLL as a resource? Once we find the
TLB, we iterate over all of the interfaces, looking for the IExodusPlugin
interface. The entire "check" function is at the end of this email. Hope this
helps.

pgm.


{---------------------------------------}
function CheckPluginDll(dll : WideString; var libname: Widestring;
    var obname: Widestring; var doc: Widestring): boolean;
var
    lib : ITypeLib;
    i, j : integer;
    tinfo, iface : ITypeInfo;
    tattr, iattr: PTypeAttr;
    r: cardinal;
begin
    // load the .dll.  This SHOULD register the bloody thing if it's not, but
that
    // doesn't seem to work for me.
    Result := false;
    try
        OleCheck(LoadTypeLibEx(PWideChar(dll), REGKIND_REGISTER, lib));
        OleCheck(lib.GetDocumentation(-1, @libname, nil, nil, nil));
    except
        on EOleSysError do exit;
    end;

    // for each type in the project
    for i := 0 to lib.GetTypeInfoCount() - 1 do begin
        // get the info about the type
        try
            OleCheck(lib.GetTypeInfo(i, tinfo));

            // get attributes of the type
            OleCheck(tinfo.GetTypeAttr(tattr));
        except
            on EOleSysError do exit;
        end;
        // is this a coclass?
        if (tattr.typekind <> TKIND_COCLASS) then continue;

        // for each interface that the coclass implements
        for j := 0 to tattr.cImplTypes - 1 do begin
            // get the type info for the interface
            try
                OleCheck(tinfo.GetRefTypeOfImplType(j, r));
                OleCheck(tinfo.GetRefTypeInfo(r, iface));

                // get the attributes of the interface
                OleCheck(iface.GetTypeAttr(iattr));
            except
                on EOleSysError do continue;
            end;

            // is this the IExodusPlugin interface?
            if  (IsEqualGUID(iattr.guid, ExodusCOM_TLB.IID_IExodusPlugin)) then
begin
                // oho!  it IS.  Get the name of this coclass, so we can show
                // what we did.  Get the doc string, just to show off.
                try
                    OleCheck(tinfo.GetDocumentation(-1, @obname, @doc, nil,
nil));
                    // SysFreeString of obname and doc needed?  In C, yes, but
here?
                    Result := true;
                    break;
                except
                    on EOleSysError do exit;
                end;

            end;
            iface.ReleaseTypeAttr(iattr);
        end;
        tinfo.ReleaseTypeAttr(tattr);
    end;
end;