Frage

Ich weiß, dass wir CoLoadLibrary und DllGetClassObject verwenden können, um die IClassFactory-Schnittstelle und die COM-Komponentenschnittstelle abzurufen, ohne die DLL zu registrieren.

Aber was ist mit einer COM-Komponente in einer EXE-Datei?Gibt es eine Möglichkeit, eine COM-Komponentenschnittstelle von einem COM-Server vom Typ EXE zu erhalten, indem ich einfach einen anderen Dateipfad bereitstelle?

War es hilfreich?

Lösung

Wenn Sie das echte Registrierung kostenlos com verwenden, Sie sollten in der Lage sein, diese Arbeit sowohl für In-Proc- als auch für Out-of-Proc-COM-Objekte zu erhalten.

Wie Sharptooth darauf hingewiesen, verwenden Sie wirklich keine Registrierung kostenlos com.Stattdessen rollen Sie wirklich Ihr eigenes, indem Sie die Anrufe fälschen, die bei der Aktivierung verwendet werden.Ihre Lösung kann funktionieren, wenn Sie sowohl Ihre Anwendung als auch den COM-Server steuern, den Sie aktivieren, aber es ist wahrscheinlich, dass es wahrscheinlich fehlschlägt.

Andere Tipps

nein, du kannst nicht.Sie benötigen COM-Setup-Marshalling zwischen Ihrem Programm und einem Out-Proc-COM-Server.Um dies zu erreichen, müssen Sie generakodicetagcode anrufen und dann entweder CoInitialize() oder CoCreateInstance().

Der Pfad, den Sie mit einem In-Proc-Server beschreiben, der generationspflichtig ist, und dann generasAnforderungen (STA / MTA-Sachen).Ein solcher schmutziger Hack ist möglich, da ein In-Proc-Server eine regelmäßige DLL mit mehreren bekannten Funktionen ist.Dasselbe ist für einen Out-Proc-COM-Server nicht möglich - Sie müssen sich in diesem Fall auf com verlassen.

Sie können eine COM-Komponente in einem Funktionsaufruf als Zeiger übergeben.

Angenommen, Sie implementieren ein Objekt in Ihrer EXE-Datei und laden dadurch ein anderes COM-Objekt aus einer DLL. Dann können Sie das EXE-basierte Objekt aus der DLL an das Objekt übergeben.Das geladene Objekt müsste eine Schnittstelle unterstützen, die über eine Funktion verfügt, die einen Zeiger akzeptiert, z. B.

interface ILoadedObject
{
    HRESULT GiveObject(IUnknown *pObj);
};

Wenn das DLL-basierte Objekt dies implementiert, können Sie es aus Ihrer EXE-Datei aufrufen und ihm ein Objekt übergeben das ist nirgendwo registriert, Daher ist es nicht erforderlich, Objekte in einer EXE-Datei zu registrieren, um dies zu erreichen.

Die einzigen Anforderungen bestehen in der korrekten Umsetzung von IUnknown:Zerstöre das Objekt erst Release wurde die richtige Anzahl von Malen aufgerufen, und stellen Sie sicher, dass QueryInterface kann verwendet werden, um zwischen einem festen Satz von Schnittstellen auf dem Objekt und dem, nach dem abgefragt wird, zu wechseln IUnknown gibt immer die gleiche Adresse zurück.

Andererseits können Sie eine EXE-Datei als Objektserver registrieren, was jedoch eine große Komplexität mit sich bringt.COM muss die EXE-Datei starten und ihr dann Nachrichten über die Windows-Nachrichtenwarteschlange senden.Dies wird nur häufig für OLE verwendet;es kann ziemlich zerbrechlich sein.

Aktualisieren

Eine umfassendere Lösung besteht darin, eine Standardmethode zum Erstellen einer Instanz eines Objekttyps zu definieren, der EXE jedoch zu erlauben, zu definieren, wie sie funktioniert.Die EXE würde Folgendes implementieren:

interface IComponent;

interface IEnvironment : IUnknown
{
    HRESULT CreateInstance(REFCLSID clsid, IComponent **ppNew);
}

Jede Komponente muss diese Schnittstelle unterstützen:

interface IComponent : IUnknown
{
    HRESULT SetEnvironment(IEnvironment *pEnv);
}

Um nun das Standardverhalten zu erhalten, bei dem die EXE-Datei die Registrierung zum Suchen von Komponenten verwenden möchte, kann sie Folgendes implementieren: CreateInstance Methode wie diese:

HRESULT Env::CreateInstance(REFCLSID clsid, IComponent **ppNew)
{
    HRESULT hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER,
                     __uuidof(IComponent), (void **)&ppNew);
    if (FAILED(hr))
        return hr;

    (*ppNew)->SetEnvironment(this);
    return S_OK;
}

Aber natürlich kann es dies ändern und einige Komponenten „einspritzen“.Daher kann anstelle (oder zusätzlich zur) der Registrierung eine Konfigurationsdatei verwendet werden.Oder (wie Sie gefragt haben) die EXE-Datei könnte integrierte Implementierungen einiger Komponenten haben:

Da jede Komponente beim Erstellen über die Umgebung informiert wird, kann sie die Umgebung zum Erstellen weiterer Komponenten verwenden:

// inside some component:
HRESULT Comp::SetEnvironment(IEnvironment *e)
{
    m_env = e; // using a smart pointer for ref-counting
    return S_OK;
}

// in some method of the component

ComPtr<IComponent> button;
m_env->CreateInstance(CLSID_Button, &button);

// now query button for more useful interface...

Wenn also eine Komponente erstellt wird, kann die Umgebung (in der EXE-Datei definiert) genau steuern, wie die Implementierung der Komponente gefunden wird.Jede Erstellung erfolgt über die EXE-Datei.

Dies wird manchmal als „Abhängigkeitsinjektion“ oder „Kontrollumkehr“ bezeichnet.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top