Callback Funktion deklarieren und anwenden ?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Benutzeravatar
snakeseven
User
Beiträge: 405
Registriert: Freitag 7. Oktober 2005, 14:37
Wohnort: Berlin
Kontaktdaten:

Callback Funktion deklarieren und anwenden ?

Beitragvon snakeseven » Donnerstag 26. Januar 2006, 11:26

Hi,
im Zusammenhang mit der COM Schnittstelle der Telefonsoftware Phoner, habe ich folgende
Antwort bekommen:

[code=]Versuche dir einfach die OnChangeState-Funktion als Callback Function vorzustellen.
So nach dem Motto: "Wenn du mir was zu sagen hast, dann rufe doch die Funktion, welche ich dir hier übergebe".
Natürlich muss die Funktionsdeklaration übereinstimmen. [/code]

Jetzt bin ich ich noch verwirrter als vorher. Ich habe noch nie mit Callbackfunktionen zu tun gehabt
und weiss nicht, wie ich die in Python deklariere und anwende.
Die oben zitierte 'OnChangeState(CallID)' Funktion ist eine Event-Funktion des COM-Servers der Software.
Den kann ich zwar ansprechen, aber die Eventfunktion will mir ihre Ergebnisse über Phoner.CPhoner.OnChangeState(CallID)
nicht übermitteln. Wie ginge der Aufruf mittels eines Callbacks ?

Habe im Wiki über Callback Funktionen nachgelesen, aber alles was ich verstanden habe ist, daß die Callback Funktion einer anderen Funktion als Parameter übergeben wird. Das hieße in meinem Fall, daß ich eine eigene Funktion 'OnChangState()' schreibe und ihr als Parameter 'Phoner.CPhoner.OnChangeState' übergebe ? Das führt aber zu einem Attribut Error.

Code: Alles auswählen

def OnChangeState(CallID):
    StateString = ""
    CallerIDString = ""
    CalledIDString = ""

    phon.GetState(CallID, StateString)
    phon.GetCallerID(CallID, CallerIDString)
    phon.GetCalledID(CallID, CalledIDString)
    return CallID

phon = win32com.client.Dispatch("Phoner.CPhoner")
print OnChangeState(phon.OnChangeState)


[code=]File "C:\Programme\Python24\Lib\site-packages\win32com\client\dynamic.py", line 489, in __getattr__
raise AttributeError, "%s.%s" % (self._username_, attr)
AttributeError: Phoner.CPhoner.OnChangeState[/code]

Gruss, Seven
modelnine
User
Beiträge: 670
Registriert: Sonntag 15. Januar 2006, 18:42
Wohnort: Celle
Kontaktdaten:

Beitragvon modelnine » Donnerstag 26. Januar 2006, 11:39

Probiers mal andersrum, also dem Attribut Deine Callback-Funktion zuzuweisen. (nur so nebenbei: callback macht genau das was drinsteht: es ist ein Rückruf. Irgendein Objekt/eine Funktion meldet sich bei Dir um Dir irgendwas mitzuteilen per Rückruf, nachdem Du sie zuerst angerufen hast)

Beispiel in Python:

Code: Alles auswählen

def meinCallback(*args):
    print "Im Callback:", args

class MeineKlasse(object):

    def __init__(self,callback):
        self._cb = callback # Speichern der Callback-Funktion entspricht der Attributzuweisung.

    def machWas(self):
        print "Ich mache was."
        for i in range(10):
            print "Mach was ist bei Schritt:", i
            self._cb(i) # Signalisiere Callback wo man gerade ist.
            time.sleep(1)

x = MeineKlasse(meinCallback)
x.machWas()


Ausführen und genießen.

Das entspräche ungefähr dem was Du machen würdest wenn Du dem Attribut OnStateChange die Callback-Funktion die Du haben willst zuweisen würdest.

--- Heiko.
Benutzeravatar
snakeseven
User
Beiträge: 405
Registriert: Freitag 7. Oktober 2005, 14:37
Wohnort: Berlin
Kontaktdaten:

Beitragvon snakeseven » Donnerstag 26. Januar 2006, 22:58

Das Beispiel ist gut, aber ich bekomme immer noch keinen Bezug zu
meiner Konstellation. Was entspricht dem Attribut 'OnChangeState' ? 'X' oder oder 'MeineKlasse' ? Und wie bekomme ich den Bezug zum COM Server Objekt ? Wenn ich mit 'Phoner.CPhoner.OnChangeState' dem Objekt versuche was zuzuweisen, bekomme ich die Meldung, dass dem Objekt nichts zugewiesen werden kann und wenn ich 'Phoner.CPhoner.OnChangeState' als Parameter übergebe, bekomme ich einen Attribut Error ?? Ich ahne zwar jetzt, worauf es hinausläuft (Daten durch die Hintertür auslesen), aber es klappt leider noch nicht :cry:
Gruß und Danke ! Seven
modelnine
User
Beiträge: 670
Registriert: Sonntag 15. Januar 2006, 18:42
Wohnort: Celle
Kontaktdaten:

Beitragvon modelnine » Donnerstag 26. Januar 2006, 23:36

Probier:

Code: Alles auswählen

phon.OnStateChange = OnStateChange


--- Heiko.
Benutzeravatar
snakeseven
User
Beiträge: 405
Registriert: Freitag 7. Oktober 2005, 14:37
Wohnort: Berlin
Kontaktdaten:

Beitragvon snakeseven » Dienstag 31. Januar 2006, 17:38

modelnine hat geschrieben:Probier:

Code: Alles auswählen

phon.OnStateChange = OnStateChange


--- Heiko.


Bringt wieder denselben Fehler:
[code=]AttributeError: Property 'Phoner.CPhoner.OnChangeState' can not be set.[/code]

Gruss, Seven
Benutzeravatar
snakeseven
User
Beiträge: 405
Registriert: Freitag 7. Oktober 2005, 14:37
Wohnort: Berlin
Kontaktdaten:

Beitragvon snakeseven » Mittwoch 1. Februar 2006, 03:46

Habe in diesem Zusammenhang von einer win32com.client-Funktion getevents() gehört, aber keine Infos darüber gefunden (der Link war nicht mehr zugänglich). Gibt es die und weiss einer, was die macht ?

Gruss, Seven
Buell
User
Beiträge: 90
Registriert: Samstag 29. Oktober 2005, 14:17

Beitragvon Buell » Mittwoch 1. Februar 2006, 12:55

win32com.client.getevents() erzeugt einen EventListener.

Bsp:

Code: Alles auswählen

class ContextEvents(win32com.client.getevents("SAPI.SpSharedRecoContext")):
    """Called when a word/phrase is successfully recognized  -
        ie it is found in a currently open grammar with a sufficiently high
        confidence"""
    def OnRecognition(self, StreamNumber, StreamPosition, RecognitionType, Result):
        newResult = win32com.client.Dispatch(Result)
        print "You said: " + str(newResult.PhraseInfo.GetText())


Wenn die COM-Schnittstelle Events erzeugt, kannst du sie damit "abhören". Dazu ist jedoch erforderlich, dass das Modul in dem der Listener läuft in einer schleife hängt, also mindestens so lange wartet bis ein Event kommt. Es empfiehlt sich deswegen das Listening in einen Thread zu packen, aber niemals das gesamte Modul, denn dann geht es nicht mehr.
Ob dir das allerdings bei deinem Problem weiterhilft...
Benutzeravatar
snakeseven
User
Beiträge: 405
Registriert: Freitag 7. Oktober 2005, 14:37
Wohnort: Berlin
Kontaktdaten:

Beitragvon snakeseven » Mittwoch 1. Februar 2006, 14:07

Danke, ich werde es zumindest versuchen. Vieleicht läßt sich damit dem OnChangeState Event auf die Schliche kommen ? Seven
Benutzeravatar
snakeseven
User
Beiträge: 405
Registriert: Freitag 7. Oktober 2005, 14:37
Wohnort: Berlin
Kontaktdaten:

Beitragvon snakeseven » Mittwoch 1. Februar 2006, 15:13

Also, um erstmal zu sehen, was getevents() überhaut macht, habe ich ein
[code=]help(win32com.client.getevents("Phoner.CPhoner"))[/code] eingegeben und das da bekommen:

[code=]Help on class ICPhonerEvents in module win32com.gen_py.98898140-96E2-11D3-A1D0-444553540000x0x1x0:

class ICPhonerEvents
| Ereignis-Schnittstelle für CPhoner-Objekt
|
| Methods defined here:
|
| __del__(self)
|
| __init__(self, oobj=None)
|
| close(self)
|
| ----------------------------------------------------------------------
| Data and other attributes defined here:
|
| CLSID = IID('{98898143-96E2-11D3-A1D0-444553540000}')
|
| CLSID_Sink = IID('{98898143-96E2-11D3-A1D0-444553540000}')
|
| coclass_clsid = IID('{98898145-96E2-11D3-A1D0-444553540000}')[/code]

Nicht das was ich erwarte habe, aber immerhin gibt es die Funktion tatsächlich und sie macht auch was :wink: Seven
Buell
User
Beiträge: 90
Registriert: Samstag 29. Oktober 2005, 14:17

Beitragvon Buell » Mittwoch 1. Februar 2006, 15:25

Ich würde mal nachsehen ob Phoner noch andere Schnittstellen hat, sieht mir ganz danach aus...
Benutzeravatar
snakeseven
User
Beiträge: 405
Registriert: Freitag 7. Oktober 2005, 14:37
Wohnort: Berlin
Kontaktdaten:

Beitragvon snakeseven » Mittwoch 1. Februar 2006, 18:26

Buell hat geschrieben:Ich würde mal nachsehen ob Phoner noch andere Schnittstellen hat, sieht mir ganz danach aus...


Ja, es hat noch eine ActiveX Schnittstelle (axphoner.ocx). Aber mit ActiveX habe ich mich noch nicht beschäftigt, obwohl es nicht viel anders sein dürfte, als COM. Aber auch da werde ich an die Events wahrscheinlich nur per Callback rankommen. Forsche also noch :) Seven
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5554
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Telfs (Tirol)
Kontaktdaten:

Beitragvon gerold » Mittwoch 1. Februar 2006, 20:09

snakeseven hat geschrieben: Aber mit ActiveX habe ich mich noch nicht beschäftigt, obwohl es nicht viel anders sein dürfte, als COM.

Hi Seven!

ActiveX ist nur ein modernerer Ausdruck für COM. Hier findest du eine ziemlich gute Einführung in Python und COM:
http://www.python.org/windows/win32com/ ... pframe.htm

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
snakeseven
User
Beiträge: 405
Registriert: Freitag 7. Oktober 2005, 14:37
Wohnort: Berlin
Kontaktdaten:

Beitragvon snakeseven » Donnerstag 2. Februar 2006, 11:58

Hi Gerold,
die Dokumentation kenne ich. Ich finde sie zu minimalistisch und auch unübersichtlich, weil alles in kleinen 'Häppchen' dargeboten wird. Außerdem sind keine Beispiele dabei. Gut finde ich die, die bei Pythonwin on board ist. Übersichtlich und mit Beispielen.
Aber daß ActiveX = COM ist, hat mich veranlasst, mal in gen_py die von makepy generierten Module von "PhonerBibliothek" und "AxPhoner" zu vergleichen. Und da steht tatsächlich fast das Gleiche drin. Und da gibt es auch definitiv keine Eventfunktion "OnChangeState". Es steht nur drin, daß man sich die selber schreiben muß. Wobei sich da die Katze in den Schwanz beißt, weil ich mir die Funktion natürlich selber schreiben kann, aber dennoch braucht diese eigene Funktion eine Schnittstelle zu COM !?
Ich werde mich aber in Zukunft auf Asterisk konzentrieren, da gibt es einfache Textscripte und die werden abgearbeitet.
Gruss, Seven

Wer ist online?

Mitglieder in diesem Forum: Bing [Bot]