Freigeben über


Verwenden der TAPI 3 MSP-Basisklassen

Im folgenden Verfahren wird beschrieben, wie Sie einen MSP mit ATL Version 2.1 oder ATL Version 3.0 und den MSP-Basisklassen implementieren. Weitere Informationen und eine Liste der Bibliotheken und Header finden Sie unter TAPI 3 MSP-Basisklassen. Der Inhalt in diesem Thema setzt voraus, dass der Entwickler über ein funktionierendes Verständnis von ATL und COM verfügt und über Erfahrung bei der Implementierung von COM-DLLs mit ATL verfügt.

So implementieren Und MSP mit ATL 2.1 oder ATL 3.0

  1. Erstellen Sie eine IDL-Datei für Ihren MSP. Diese Datei definiert eine CLSID für Ihren MSP. Deklarieren Sie Ihre MSP-Co-Klasse als Implementieren der ITMSPAddress-Schnittstelle , und deklarieren Sie diese Schnittstelle als Standardschnittstelle für Ihr Klassenobjekt. Importieren Sie für die Definition von ITMSPAddress die Datei "msp.idl". Schließen Sie Ihre MSP-"Co-Klasse" in eine Typbibliothek für Ihren MSP ein. Wenn Ihr MSP private (benutzerdefinierte) Schnittstellen unterstützt, definieren Sie diese hier, und fügen Sie sie in Ihre Typbibliothek ein. Das folgende Codebeispiel ist eine IDL-Datei, wie oben beschrieben, ohne benutzerdefinierte Schnittstellen.

    import "msp.idl";
    [
          uuid(4DDB6D35-3BC1-11d2-86F2-006008B0E5D2),
          version(2.0),
          helpstring("Wave MSP 2.0 Type Library")
    ]
    library WAVEMSPLib
    {
    importlib("stdole32.tlb");
    importlib("stdole2.tlb");
    
    [
    uuid(4DDB6D36-3BC1-11d2-86F2-006008B0E5D2),
    helpstring("Wave MSP Class")
    ]
    coclass WaveMSP
    {
    [default] interface ITMSPAddress;
    };
    };
    
  2. Ändern Sie Ihren TSP, um die CLSID Ihres MSP anzukündigen, wenn Tapi3.dll sie anfordert. Stellen Sie sicher, dass (1) Ihr TSP TAPI_VERSION3_0 oder höher in der TSPI-Funktion TSPI_lineNegotiateTSPIVersion aushandeln kann, (2) Ihre TSP LINEDEVCAPS-Struktur das LINEDEVCAPFLAGS_MSP Flag im dwDevCapFlags-Member festgelegt hat, und (3) Ihr TSP gibt Ihre MSP CLSID in der TSPI-Funktion TSPI_lineMSPIdentify zurück. Dies sollte dieselbe CLSID sein, die in Ihrer IDL-Datei angegeben ist. Beispielsweise die zweite Zeile "uuid" in der IDL-Beispieldatei im vorherigen Schritt.

  3. Kompilieren Sie die MSPBase-Beispielanwendung im Platform Software Development Kit (SDK), um die Bibliothek MSPBaseSample.lib zu erstellen.

  4. Verknüpfen Sie Ihre MSP-DLL mit der Bibliothek MSPBaseSample.lib.

  5. Schließen Sie Mspbase.h aus dem SDK für MSP-Basisklassendefinitionen ein.

  6. Implementieren Sie Ihre DLL-Exporte (z. B. DllMain). Microsoft Visual C++ generieren diese für Sie. Verwenden Sie in DllMain auf DLL_PROCESS_ATTACH bzw. DLL_PROCESS_DETACH die Makros MSPLOGREGISTER und MSPLOGDEREGISTER , um Protokollierungsfeatures für Ihre DLL zu aktivieren. Geben Sie den Namen Ihrer DLL im MSPLOGDEREGISTER-Aufruf an.

  7. Verwenden Sie das in Msplog.h definierte LOG-Makro, um Ablaufverfolgungsmeldungen auf die gleiche Weise wie die Basisklassen auszugeben. Definieren Sie das MSPLOG-Präprozessorsymbol, um die Protokollierung in Ihre DLL einzuschließen. Lassen Sie es nicht definiert, um eine DLL ohne Protokollierung zu erstellen.

  8. Leiten Sie eine Klasse von CMSPAddress ab, die Adressen für Ihren MSP implementiert. Deklarieren Sie eine globale ATL-Objektzuordnung, die ATL anweist, eine instance Ihrer Adressklasse zu erstellen, wenn Sie zu CoCreate für die CLSID aufgefordert werden, die Sie in Ihrer IDL-Datei angegeben haben. Leiten Sie außerdem Ihre Adressklasse von der ATL CComCoClass-Vorlage ab, und fügen Sie eine DECLARE_REGISTRY_RESOURCEID-Deklaration in Ihre Adressklasse ein. Erstellen Sie ein entsprechendes Ressourcenskript und eine Headerdatei, wie bei jeder anderen ATL COM-DLL.

  9. Implementieren Sie die erforderlichen CMSPAddress-Außerkraftsetzungen für Ihre Adressklasse. Rufen Sie für MSPAddressAddRef und MSPAddressRelease die bereitgestellten Hilfsfunktionsvorlagen auf. Für GetCallMediaTypes geben Sie einfach eine DWORD-Bitmap mit allen MSP-unterstützten TAPIMEDIAMODEs ORed zurück. Geben Sie für CreateMSPCall und ShutdownMSPCall E_NOTIMPL zurück, kompilieren und verknüpfen Sie ihren MSP an diesem Punkt. Vergewissern Sie sich nun, dass Sie Ihren MSP über TAPI 3-Anwendungen registrieren und instanziieren können, aber nicht erfolgreich Aufrufe erstellen können.

  10. Leiten Sie eine Klasse von CMSPCallMultiGraph ab, um Ihre MSP-Aufrufobjekte zu implementieren. Sie können von CMSPCallBase anstelle von CMSPCallMultiGraph ableiten, wenn das filter-graph-per-stream-Modell nicht Ihren Anforderungen entspricht. dies erhöht die Komplexität der Aufgabe (ab diesem Schreiben leiten alle MSPs Aufrufobjekte direkt von CMSPCallMultiGraph ab). Implementieren Sie in Ihrem Adressobjekt CreateMSPCall und ShutdownMSPCall , um Ihren spezifischen Typ des Aufrufobjekts mithilfe der bereitgestellten Hilfsfunktionsvorlagen zu erstellen und herunterzufahren. Überschreiben Sie createStreamObject in Ihrem Aufrufobjekt, um E_NOTIMPL zurückzugeben. Überschreiben Sie MSPCallAddRef und MSPCallRelease in einer Weise, die mit den entsprechenden Adressmethoden identisch ist. Auch hier sollten Sie in der Lage sein, Ihren MSP zu kompilieren und zu verknüpfen. Es sollte jetzt in der Lage sein, Anrufe zu erstellen und zu beenden, aber die Aufrufe führen kein nützliches Streaming aus.

  11. Leiten Sie eine Klasse von CMSPStream ab, um Ihre MSP-Streamobjekte zu implementieren. Implementieren Sie in Ihrem Aufrufobjekt CreateStreamObject , um Ihr Streamobjekt zu erstellen und zu initialisieren (in der Regel durch Aufrufen der ATL CreateInstance gefolgt von der ATL- _InternalQueryInterface für ITStream , gefolgt vom Aufrufen von Init für Ihr Streamobjekt). Um eine feste Anzahl von Streams zu unterstützen (dies ist üblich für MSPs, die keine Änderung von Streamkonfigurationen durch andere Endpunkte des Aufrufs unterstützen), überschreiben Sie Init, CreateStream und RemoveStream für Ihr Aufrufobjekt. (Der Aufruf Init erstellt zunächst alle Datenströme, und CreateStream und RemoveStream geben die entsprechenden TAPI-Fehlercodes zurück, um zu verhindern, dass die Anwendung Streams erstellt oder entfernt. Andernfalls überschreiben Sie die Init-Methode des Aufrufs, um eine anfängliche Standardkonfiguration von Streams unter Verwendung der für den Aufruf angeforderten Medientypen zu erstellen. Verwenden Sie beim Erstellen von Standardstreamobjekten in der Init-Methode Ihres Aufrufs die InternalCreateStream-Hilfsmethode .

  12. Implementieren Sie Ihr Streamobjekt. Die einzige erforderliche Überschreibung ist die get_Name-Methode , die einfach einen Anzeigenamen für den Stream zurückgibt. Darüber hinaus müssen Sie mehrere andere Methoden außer Kraft setzen. Welche Methoden genau überschrieben werden sollen, hängt von Ihrer Implementierung ab und wann Sie sich entscheiden, die verschiedenen Aufgaben auszuführen, die mit dem Erstellen und Dekonstruieren Ihres Filterdiagramms verbunden sind. Zu diesen Aufgaben gehören das Erstellen der entsprechenden "Transport"-Filter, Codecs usw. sowie deren Einfügen und Entfernen aus den Filterdiagrammen zu den entsprechenden Zeitpunkten. Sie müssen auch die ITTerminalControl-Schnittstelle für Terminalobjekte verwenden, um die ausgewählten Terminals mit Ihren Streams zu verbinden. Sie können SelectTerminal und UnselectTerminal für Ihr Streamobjekt außer Kraft setzen, um die Terminalkonfigurationen einzuschränken, die Ihre Streams akzeptieren. Die Beschränkung jedes Datenstroms auf ein einzelnes Terminal vereinfacht insbesondere die Erstellung Ihrer Filterdiagramme, opfert jedoch Anwendungsfunktionen wie die Videovorschau. Abhängig von Ihrer Implementierung platzieren Sie Ihre Diagrammkonstruktion, Dekonstruktion und Terminalverbindungscode in den Methoden StartStream, StopStream, PauseStream, Initialize, Shutdown, SelectTerminal und UnselectTerminal oder in Ihren eigenen Methoden, die auf der privaten TSP-Kommunikation basieren. Beachten Sie, dass ein Stream ohne ausgewählte Terminals den gewünschten Graphzustand nachverfolgen muss. Ein StartStream-Aufruf gefolgt von einem SelectTerminal-Aufruf für einen solchen Stream muss zu einem Datenstrom führen. Überschreiben Sie die meisten dieser Methoden, um sicherzustellen, dass die richtige Konstruktion, Dekonstruktion, Verbindung und Trennung in jedem Fall abhängig vom Zustand des Datenstroms erfolgt.

  13. Implementieren Sie Ihre TSP-Kommunikation. Überschreiben Sie CMSPAddress::ReceiveTSPAddressData und/oder CMSPCallBase::ReceiveTSPCallData und/oder, indem Sie PostEvent für Ihr Adressobjekt oder HandleStreamEvent für Ihr Anrufobjekt (entweder aus Ihrem Anruf- oder Streamobjekt) aufrufen.

  14. Verwenden Sie PostEvent für Ihr Adressobjekt oder HandleStreamEvent für Ihr Aufrufobjekt (entweder von Ihrem Aufruf- oder Streamobjekt), um Anrufmedienereignisse über Tapi3.dll an die Anwendung zu senden. Dies geschieht in der Regel für Ihr Streamobjekt in überschriebenen Methoden, einschließlich der Methoden ProcessGraphEvent, StopStream, StartStream, PauseStream, SelectTerminal und UnselectTerminal , je nachdem, wie Sie Ihre Streams implementieren.

  15. Implementieren Sie alle gewünschten privaten Schnittstellen oder Unterstreams für Ihre vorhandenen Objekte (Adresse, Aufruf und Stream). In der Regel gibt es keine. Beachten Sie, dass Sie beim Implementieren Ihrer privaten Schnittstellen die LIBID Ihrer Typbibliothek aus Ihrer IDL-Datei angeben. Das heißt, Anwendungsprogrammierer müssen Ihre MSP-Typbibliothek verwenden, wenn Sie Ihre benutzerdefinierten Schnittstellen verwenden. Die in den MSP-Basisklassen implementierten MSP-Standardschnittstellen verwenden die Tapi3.dll LIBID und sind daher für alle TAPI 3-Anwendungen zugänglich.

  16. Wenn Sie MSP-spezifische statische oder dynamische Terminalobjekte oder Ersetzungen für die statischen Standardterminals (nicht typisch) implementieren, können Sie die bereitgestellten Terminalbasisklassen verwenden. Sie müssen verschiedene Methoden für Ihr Adressobjekt überschreiben, um alternative oder zusätzliche Methoden zum Erstellen von Terminalobjekten bereitzustellen.

  17. Implementieren Sie die IObjectSafety-Schnittstelle für Ihre Address-, Call-, Stream- und Terminalobjekte. Wenn Sie dispatch Mapper verwenden möchten, um Schnittstellen für Ihre MSP-Objekte abzufragen, markieren Sie Ihre Objekte als sicher für die Skripterstellung auf diesen Schnittstellen. Implementieren Sie hierzu die IObjectSafety-Schnittstelle für Ihr Objekt. Durch Ableiten von CMSPObjectSafetyImpl (einer hilfsbasierten Klasse, die in Msputils.h bereitgestellt wird) und das Hinzufügen von IObjectSafety zum ATL-COM_MAP Ihrer Klasse werden Ihre Objekte für Skripterstellung auf allen verfügbaren Schnittstellen geschützt. Beachten Sie, dass die Verwendung von Dispatch Mapper für MSP-Objekte implizit sein kann. MSP-Adresse und MSP-Aufruf werden durch TAPI-Adress- und TAPI-Aufrufobjekte aggregiert. Wenn Dispatch Mapper für die TAPI-Objekte verwendet wird, um die Schnittstellen abzufragen, die von den aggregierten MSP-Objekten verfügbar gemacht werden, werden die aggregierten MSP-Objekte zur Sicherheit der angeforderten Schnittstellen abgefragt.