c ++ - DLL-baseret applikationsramme med tovejs grænseflader (Windows)

Indlæg af Hanne Mølgaard Plasc

Problem



Løst



this var ikke problemet, da det er implicit kastet til IFramework alligevel.


Jeg var bekymret for, at det kunne have med mine metoder ikke at vende tilbage HRESULT eller med mine stumpede implementeringer af IUnknown::QueryInterface, men det virkelige problem var blot en compilerindstilling, der havde tilsidesat flere makroer, jeg havde brug for til almindelig opkald konventioner (måske skulle jeg have inkluderet dem i spørgsmålet). Dette havde beskadiget stakken.


Det er interessant, at det fungerede, at alle kompilatorer jeg testede, selv uden at implementere IUnknown overhovedet - viser en lille undersøgelse, at alle seriøse Windows-kompilere håndterer abstrakte C ++-interfaces på samme måde - nemlig som et virtuelt bord, der specifikt skal bruges som en COM interface.





Hej. Jeg forsøger at skabe en udvidelig applikationsramme. Mit grundlæggende koncept er dette:


Framework Schematics


Rammen 'Ramme' vil opbygge en .exe, mens de flere 'Plugin' -bokse vil bygge .dll-filer.


Men min implementering er tilsyneladende fejlfri. Jeg har en ide om, hvad der er problemet, men jeg løber tør for løsninger. Jeg har gjort det nøjagtigt med dette med .NET-projekter, men det problem, jeg har nu, har ikke været tilfældet med C # -miljøet.


Overvej disse grænseflader:


class IFramework
{
public:
    virtual void FrameworkMethod() = 0;
};

class IPlugin
{
public:
    virtual void PluginMethod() = 0;
    virtual void PluginCallbackTest() = 0;
    virtual void SetFramework(IFramework *framework) = 0;
};


Gennemførelse af rammen:


class CFramework : IFramework
{
public:
    void FrameworkMethod(); // printf("FrameworkMethod");
    void DoSomething(); // this is the testbench basically, see below
};


Og implementeringen af ​​plugin:


class CPlugin : public IPlugin
{
    IFramework *Framework;
public:
    void PluginMethod(); // printf("PluginMethod");
    void PluginCallbackTest(); // Framework->FrameworkMethod();
    void SetFramework(IFramework *framework); // Framework = framework;
};
// plugin factory -> COM interface
extern "C" PLUGIN\_API IPlugin *GetPlugin(); // return new CPlugin;


Nu for at demonstrere, at dette koncept ikke virker:


void CFramework::DoSomething()
{
    HMODULE PluginHandle = LoadLibrary(...); // explicit linking
    auto GetPlugin = ((IPlugin *)(*)())GetProcAddress(...);
    IPlugin *plugin = GetPlugin();
    plugin->PluginMethod();
    // up until here everything's perfectly COM-compliant and works super
    plugin->SetFramework(this); // <-- that is the problem 
    plugin->PluginCallbackTest(); // <-- runtime crash if compiler differs
    FreeLibrary(PluginHandle);
}


Problemet er, at SetFramework(this) virker ikke som COM. Det er ikke, at det bare føles forkert at skrive det som sådan - jeg kan ikke implementere en arbejdsplugin med en compiler, der adskiller sig fra den, jeg brugte at bygge CFramework (kørselstidsbrud).

Bedste reference


Hvis du vil tillade forskellige compilere til plugin-modulerne fra det, du bruger til appen, skal du bruge COM udelukkende på tværs af grænsen mellem app og plug-ins. Det er netop det problem, som COM blev designet til at løse.