Python 駸 COM
dokumentum verzi?k:
- 1.1 verzi?(2000年07月25日.):
- kimaradt az el?z? verzi?b?l a CoInitialize 駸 CoUnitialize f?ggv駭yek haszn疝ata,
- a makepy.py haszn疝at疉oz adtam n駑i kieg駸z?t駸t,
- a forr疽okat form痙tam
- 1.0 verzi?(2000年06月23日.): ezt m疵 haszn疝hat?nak it駘tem
Ezzel a le?r疽sal azoknak akarok seg?teni, akik kezd?k a fenti t駑ak?rben 駸
m疵 megfogalmaz?dott benn?k az al畸bi k駻d駸ek valamelyike:
A cikkben szerepl? mintaprogramok kipr?b疝疽疉oz sz?ks馮ed lesz a k?vetkez?kre:
- Windows 9x, Windows NT vagy Windows 2000 oper當i?s rendszer.
- Python telep?t? k駸zlet a fenti oper當i?s rendszerekhez
- Mark Hammond win32all csomagja
- Windows 95 eset饕en tal疣 COM friss?t駸 is kell, de ebben nem vagyok biztos...
- Microsoft Office
- Magukra a minta programokra
Egyfajta bin疵is/h疝?zati szabv疣y szoftver komponensek haszn疝at疵a 駸
egy?ttm?k?d駸駻e. A COM ?n. interf駸zekkel dolgozik, amiken kereszt?l
hozz畴駻het?nk a komponensek funkcionalit疽疉oz. A COM maga is el?re defini疝
egy rakat interf駸zt. Egy interf駸z val?j畸an egy "virtual base class", m疵
akinek ez a C++-os hablaty mond valamit. Nek?nk jelenleg el馮, ha egy interf駸z
kapcs疣 egy olyan class-ra gondolunk, akinek mindef駘e met?dusai vannak, de a
met?dusok implement當i?j疸 nem az interf駸z maga hanem egy m疽ik class - a COM
class - tartalmazza. T?bb interf駸z is tartozhat egy ilyen COM class-hoz, s?t a
gyakorlatban legal畸b kett? interf駸ze mindig van.
Azt is szokt疚 mondani, hogy egy interf駸z nem m疽 mint egy kommunik當i?s
szerz?d駸 a komponens 駸 a kliens program k?z?tt. P駘d疼l egy bizonyos interf駸zt
k?l?nb?z? komponensek teljesen elt駻? m?don is implement疝hatnak, de az ?ket
haszn疝? kliens program sz疥疵a ez nem is l駭yeges. Gondoljatok az ActiveX kontrolokra:
mindegyik m疽k駱p n騷 ki 駸 m疽 c駘t szolg疝(textbox, label, listbox stb.), de m馮is
t疥ogatnak olyan el?re specifik疝t interf駸zeket, amit?l ?k ActiveX kontrolokk? v疝nak
(駸 pl. a VB fejleszt? k?rnyezet饕en egys馮es haszn疝atot/viselked駸t eredm駭yeznek).
Egy COM komponens fizikailag valamilyen modulban tal疝hat?, ami lehet:
- egy dll. Ezt szok疽 inprocess szervernek is nevezni.
- egy exe. Ezt szok疽 out of process szervernek nevezni.
Mivel COM komponenseket haszn疝hatunk ?gy is, hogy a komponens, amit haszn疝unk
fizikailag egy m疽ik g駱en fut, ebben az esetben egy dll is out of process lesz!
A COM bin疵is volta miatt nem nyelvf?gg? megval?s?t疽. Term駸zetesen a k?l?nb?z?
programoz疽 nyelvekben 駸 fejleszt? k?rnyezetekben a COM t疥ogatotts疊a elt駻?. P駘d疼l
Visual Basic-ben API haszn疝at n駘k?l csak a default interf駸z 駻het? el 駸 nem lehet
"m疽zk疝ni" az interf駸zek k?z?tt. A bin疵is volta miatt sz?ks馮 van valamilyen
nyelvf?ggetlen eszk?zre, ami inform當i?t szolg疝tat a komponensekr?l a k?l?nb?z?
fejleszt? eszk?z?knek. Erre gyakorlatilag k騁 megold疽t k?n疝 a Microsoft:
- IDL(Interface Definition Language): ez egy Ascii f疔l, ami le?rja a
komponensek funkcionalit疽疸.
- Type Library: ez az IDL f疔l bin疵is form疔a, ami vagy k?l?n .tlb f疔lban
van vagy maga a modul tartalmazza.
A COM a komponensek, interf駸zek 駸 gyakorlatilag mindennek az azonos?t疽疵a 128 bit
hossz? sz疥okat haszn疝, amir?l az 疝l?tja hogy igen nagy val?sz?n?s馮gel nem fordul el?
k騁 azonos. Lehet ProgId-vel is hivatkozni, ami egy besz馘es n騅, de mivel ez a fejleszt?
tal疝m疣ya ebb?l lehet azonos. A COM csak a 128 bites azonos?t?knak hisz. T?bb fajta
elnevez駸?k is van ezeknek az ID-knek, ami a felhaszn疝疽i ter?let?kre utal:
- GUID: Globally Unique ID
- UUID: Universally Unique ID
- CLSID: COM class azonos?t?
- IID: interf駸z azonos?t?
ID el?疝l?t疽a lehets馮es: API h?v疽sal, guidgen.exe-vel stb.
N馼疣y a COM 疝tal el?re defini疝t interf駸z:
- IUnknown: ebb?l sz疵mazik minden m疽 interf駸z, ez駻t h疵om met?dusa
minden interf駸zben megtal疝hat?:
- QueryInterface: ezzel lehet egy IID-val azonos?tott m疽ik interf駸zre 疸menni
- AddRef: a bels? refcount-ot n?veli
- Release: a bels? refcount-ot cs?kkenti 駸 ha ez 0-v? v疝t, akkor kit?rli a komponenst
- IDispatch: n馼a automation interf駸zk駭t is hivatkoznak r?. Legfontosabb met?dusa az
Invoke, ami param騁erk駭t a megh?vand? met?dus nev騁 駸 annak param騁ereit kapja meg.
Ez az interf駸z dinamikus met?dus h?v疽t/haszn疝atot tesz lehet?v?.
- IClassFactory: ez az interf駸ze(IUnknown-on k?v?l) a m疽ik COM class-nak,
ami minden modulban benne van. Ez a "COM class gy疵" interf駸z,
szab疝yosan ennek haszn疝at疱al hozunk l騁re egy ?j instance-ot.
Direktben nem nagyon haszn疝juk, de p駘d疼l CoCreateInstance COM API is ezt haszn疝ja.
- IConnectionPointContainer, IConnectionPoint: ha vannak esem駭yek is, akkor ezekre az interf駸zekre
van sz?ks馮 ahhoz, hogy a komponensnek az esem駭ykezel?nket(sink) 疸 tudjuk adni.
Nem volt c駘om, hogy 5 mondatban megvil疊?tsam a COM minden rejtelm騁, csak
annyit akartam a COM-r?l ?rni, hogy az alapj疣 a python-os anyag 駸 programok m疵
駻thet?ek legyen. V馮?l m馮 egy r?vid terminol?giai sz?t疵, ami tov畸bi COM-os cikkek
meg駻t駸饕en lehet seg?ts馮edre:
- Modul: dll vagy exe, ami az eg駸z moty?t tartalmazza
- COM class: vagy component class, vagy COM object. ユ val?s?tja meg a funkcionalit疽t. ユt fogjuk el駻ni k?l?nb?z? interf駸zeken kereszt?l. Gyakorlatilag az interf駸zeknek ? mint virtual base class-oknak ? a lesz疵mazottja.
- Interface: ez egy virtual base class, aminek a met?dusait majd inplemet疝nunk kell a COM class-ban. Az angol doksikban el?szerettel emlegetik az interf駸zeket mit egyfajta szerz?d駸 a kliens 駸 a szerver k?z?tt(verzi? k?vet駸).
- Class object: vagy class factory, vagy class factory object. T?bbnyire minden modulban van egy ilyen. Ki lehet hagyni, ha csak nagyon fapados API-kat haszn疝unk, de a c駘ja az hogy magaszint? API-kat haszn疝va seg?ts馮騅el 疝l?tsuk el? az instance-okat. A ?location transparency? az ami miatt fapados API-k haszn疝ata nem javasolt 駸 jobb ha szerver?nkben implemet疝unk egy class factory-t, mert akkor az infrastrukt?ra megk?m駘 benn?nket egy csom? rabszolgamunk疸?l. Ez egy speci疝is COM class, akinek legal畸b egy inter駸ze van az IClassFactory. Feladata instance-ok l騁rehoz疽a a COM class-okb?l.
- Dual interface az az interface, aminek met?dusait vtable-n kereszt?l 駸 IDispatch::Invoke seg?ts馮騅el is el tudjuk 駻ni.
- [OLE] Automation az a funkcionalit疽, amit IDispatch 肪?l sz疵maztatott interface-en kereszt?l 駻het?nk el. COM el?tt is l騁ez? technol?gia, ami mint egy interface 駱?lt be a COM-ba.
- Proxy: a TCP/IP-s proxy-hoz hasonl? funkcionalit疽?. Proxy-ra van sz?ks馮 pl. egy out of process komponens el駻駸e sor疣, ekkor a kliens a proxy-n kereszt?l kapcsol?dik a szerverhez. A kliens sz疥疵a ez l疸hatatlan az infrastrukt?ra automatikusan l騁rehozza, ha sz?ks馮 van r?.
- Stub: a proxy p疵ja a szerver oldalon, ? reprezent疝ja a klienst a szerver sz疥疵a a szerver processben.
- Sink: a kliens oldalon l騁rehozott COM instance akinek az IUnknown interf駸z騁 adjuk 疸 egy connection point-nak. A sink-ben t?rt駭ik az esem駭yek kezel駸e.
- Aggregation 駸 containment/delegation : mind a k騁 esetben egy COM komponens m疽 COM komponenseket haszn疝 a funkci?k implemet疝疽a sor疣. Containment/delegation-r?l besz駘?nk, ha a k?ls? komponens felhaszn疝ja a bels?k interf駸zeit a saj疸 interf駸zek implemet疝疽a sor疣. Aggregation-r?l besz駘?nk, ha a k?ls? komponens egy vagy t?bb interf駸z騁 nem implemet疝ja, hanem egy m疽ik COM komponens interf駸z騁 haszn疝ja, ami k?v?lr?l ?gy l疸szik mintha a k?ls?ben lenne az implement當i?.
- Reference counting: ezzel k?vetj?k egy, hogy egy instance-ot haszn疝-e m馮 valaki, vagy m疵 t?r?lhet?.
- Inprocess szerver: mikor a szerver komponens fizikai megjelen駸e dll 駸 a kliens is a szerver is azonos g駱en fut. Ekkor a kliens process-en bel?l l騁ezik a szerver komponens.
- Out of process szerver: mikor a szerver exe vagy olyan dll, akit h疝?zaton kereszt?l egy m疽ik g駱en 駻?nk el. Ha dll a szerver 駸 egy m疽ik g駱en fut, akkor term駸zetesen a COM biztos?t egy process-t a sz疥疵a, amin bel?l futni fog, azaz a fejleszt?nek nem kell felt騁len?l extra er?fesz?t駸eket tennie az駻t hogy inprocess szerver騁 h疝?zaton kereszt?l t疱oli g駱r?l futtass疚.
- Type Library: lehet ?n疝l? f疔l vagy tartalmazhatja a modul is. Az interf駸z defin?ci?kat tartalmazza bin疵is form疸umban(mint az IDL f疔l, de az ASCII).
A Python lehet?s馮et ad arra, hogy a COM-ot azon a szinten kezelj?k, amire
mondjuk C++-ban van lehet?s馮, de t疥ogatja a m疽ik v馮letet is - amire j? p駘da
Visual Basic - mikor a m?k?d駸i mechanizmus nagy r駸ze rejtve marad el?l?nk.
Legegyszer?bb eset: Dispatch haszn疝ata
Ha nincs esem駭ykezel駸 駸, akkor legegyszer?bb a win32com.client.Dispatch haszn疝ata. A
win32com.client.Dispatch maga d?nti el, hogy dinamikusan haszn疝ja a komponenst vagy statikusan.
A makepy.py utility seg?ts馮騅el el?re legenr疝hatunk t疥ogat? class-okat a COM komponenshez, ami
bizonyos esetekben stabilabb m?k?d駸t eredm駭yez(tipus ellen?rz駸 stb.). A legut?bbi win32all (build 132)
eset饕en m疵 a t疥ogat? class-ok package-be vannak szervezve 駸 csak azok a class-ok vannak t駭ylegesen
legener疝va akiket haszn疝ni akarunk. A makepy.py haszn疝ata '-i' param騁errel ki?r az outputra n馼疣y sort,
amit script?nkbe m疽olva biztos?tani tudjuk, hogy a t疥ogat? classok mindenk駱pen l騁ezzenek. A scriptek v馮駭
aj疣lott megh?vni a pythoncom.CoUninitalize f?ggv駭yt. Minden thread-ben miel?tt COM-ot haszn疝n疣k meg kell
h?vni a pythoncom.CoInitialize vagy a pythoncom.CoInitializeEx f?ggv駭yeket. Ezekben a p駘d疚ban az駻t nem h?vjuk meg,
mert a f? thread-ben az "import pythoncom" kiad疽疱al automatikusan megh?v疽ra ker?l a pythoncom.CoInitialize. Figyelem:
egy thread-ben t?bbsz?r is h?vhat? a pythoncom.CoInitialize vagy a pythoncom.CoInitializeEx(azonos param騁errel),
de ugyan annyi pythoncom.CoUninitalize h?v疽ra is sz?ks馮 van.
A p駘da program Excel automation-t mutat be.
Python forr疽
Esem駭yek kezel駸e, ha van type library: DispatchWithEvents haszn疝ata
Esem駭ykezel駸hez a kliens oldalon egy sink-re, egy minim疝is COM class-ra van sz?ks馮. A sink
IUnknown interf駸z騁 adjuk 疸 a megfelel? connection point -nak(Advise met?dus). Python-ban ebb?l
a legegyszer?bb esetben szinte semmit sem l疸unk csak egy class-t, akinek "On"+esem駭yn騅 nev? met?dusai vannak.
A DispatchWithEvents-nek param騁erk駭t 疸adjuk ezt a class-t, a t?bbit elint騷i a m?g?ttes infrastrukt?ra. Ez
a megold疽 type library-t ig駭yel. Ha m馮 nincs python class gener疝va a type library-b?l, akkor
meg fog jelenni a makepy.py progress bar-ja is(m疽odszori futtat疽n疝 m疵 nem). A p駘d畸an Word-?t ind?tunk el,
majd kil駱?nk bel?le 駸 a kil駱駸 t駭y騁 - mint esem駭yt - kapjuk el.
FIGYELEM: eddig kisbet?/nagybet? nem sz疥?tott, de mivel t疥ogat? Python
class-ok lettek gener疝va itt sz疥?t ez is!
A win32com\gen_py al? ker?lnek a gener疝t modulok, ahol az esem駭yeket kezel? met?dusok protot?pusait is megtal疝juk.
Python forr疽
Esem駭yek kezel駸e, ha nincs type library: DispatchWithEvents megker?l駸e
Type library hi疣y畸an az el?z? egyszer? m?dszer nem j疵hat?, k駭ytelenek vagyunk
egy kicsit alacsonyabb szintre menni. A p駘da az ebben a cikkben ismertetett python szerver komponenst haszn疝ja.
Python forr疽
Nem lok疝is komponensek el駻駸e: DispatchEx haszn疝ata
Mi van, ha az els? p駘d疸(Excel automation) ?gy akarjuk megcsin疝ni, hogy az
Excel egy m疽ik g駱en fusson? A python forr疽ban minim疝is v疝toz疽ra van sz?ks馮:
Dispatch helyett DispatchEx-t kell haszn疝ni, mert az ut?bbinak azt is meg lehet mondani,
hogy melyik g駱en hozza l騁re a komponenst. A p駘da m?k?d駸馼ez sz?ks馮es a rendszer 疸konfigur疝疽a is!
Csak Windows NT-re tudom, hogy mit kell csin疝ni mert csak ezt haszn疝unk.
A dcomcnfg.exe seg?ts馮騅el a t疱oli g駱en:
- enged駘yezt?k a DCOM-ot
- magunknak adjunk jogot komponens ind?t疽ra/manipul疝疽ra(default launch/access permission).
- Az Excel eset饕en 疝l?tsuk be, hogy az identity az interactive user legyen(csak az駻t, hogy Task Manageren kereszt?l is piszk疝hat? legyen) a security pedig a default be疝l?t疽okkal m?k?dj?n.
A dcomcnfg.exe seg?ts馮騅el a lok疝is g駱en enged駘yezz?k a DCOM-ot. Ez kell mert alap駻telmez駸 szerint nincs enged駘yezve.
A p駘da szint駭 Excel-t, haszn疝 駸 megegyezik a kor畸bi p駘d疱al csak most az Excel a t疱oli g駱en fut.
Python forr疽
Term駸zetesen a v疝asz igen. Python-ban nincs "virtual base class" fogalom mint C++-ban,
ez駻t az interf駸zek nem ?n疝l? class-okk駭t jelennek meg. Nagyon leegyszer?s?tve a
COM komponens gy疵t疽疣ak menete Python-ban:
- L騁rehozunk egy class-t azokkal a met?dusokkal, amelyek - egy r駸ze vagy mind - majd a
a komponens?nk egyetlen interf駸z駭ek met?dusai lesznek.
- A class-nak lesz n馼疣y speci疝is tulajdons疊a, amit a m?g?ttes infrastrukt?ra haszn疝
fel a komponensk駭t publik疝疽 sor疣:
- _public_methods_: azokat a met?dusokat kell egy list畸an felsorolni(a nev?ket), akiket meg
akarunk jelen?teni a COM interf駸z?nk met?dusak駭t
- _public_attrs_: azokat a tulajdons疊okat kell egy list畸an felsorolni(a nev?ket), akiket meg
akarunk jelen?teni a COM interf駸z?nk met?dusak駭t
- _reg_desc_: valami duma a komponens?nkr?l
- _reg_clsid_: class azonos?t?, amit valamilyen m?don el? kell 疝l?tani(guidgen.exe, pythoncom.CreateGuid() stb.)
- _reg_progid_: ez lesz a ProgId, amit p駘d疼l Python-b?l vagy
Visual Basic-b?l haszn疝hatunk
- A python modulunkhoz hozz疳akolunk egy n馼疣y soros regisztr當i?s k?dot.
Ezzel k駸z is vagyunk. Lefuttava a regisztr當i?s k?dot m疵is haszn疝atba vehetj?k
a frissen elk駸z?lt COM komponens?nket.
A mintak駭t mell駝elt p駘da egyetlen met?dusa az echo, ami annyiszor visszhangozza
a kapott param騁ert, amennyi a publikus count tulajdons疊ban be van 疝l?tva.
Python forr疽
Esem駭yek gener疝疽疉oz m馮 n駑i kieg駸z?t駸re van sz?ks馮?nk. Valahogy IConnectionPoint,
IConnectionPointContainer interf駸zekkel kell kieg駸z?teni a komponens?nket:
- Azonos?t?kat kell gener疝nunk a connection point interf駸zeinknek.
- A class-unkat a "win32com.server.connect.ConnectableServer"-b?l kell sz疵maztatni.
Ez fogja biztos?tani a fentebb eml?tett interf駸zek kezel駸騁 a sz疥unkra.
- A _connect_interfaces_ class v疝toz?ban(lista) fel kell sorolni a connection point interf駸zek
azonos?t?it(hogy ConnectableServer tudja kikr?l van sz?).
- Figyelni kell r?, hogy a _public_methods_ class v疝toz? a ConnectableServer public met?dusait
is tartalmazza.
- A class-unknak legyen __init__ met?dusa, ahol h?vjuk meg a ConnectableServer __init__ met?dus疸.
- Sz?ks馮?nk van m馮 egy met?dusra, akit a ConnectableServer _BroadcastNotify met?dus疣ak adunk meg
param騁erk駭t, mikor esem駭yt gener疝unk.
Az el?z? p駘da m?dos?t疽a: az echo met?dus "IntVolt" esem駭yt gener疝, ha a param騁er int tipus?, azaz egy
connection point interf駸z?nk lesz egyetlen event-el(IntVolt).
FIGYELEM: Visual Basic-b?l ezt az esem駭yt nem tudjuk kezelni, mert a "Dim WithEvents" nyelvi lehet?s馮
type library-ra 駱?l, az meg itt nincs!
Python forr疽
Di?h駘yban ennyi a COM komponensek k駸z?t駸e Python-ban.
ヨsszegz駸
Rem駘em a cikk el馮s馮es inform當i?kat tartalmaz a Python-COM p疵os haszn疝at疉oz. Egy k駸?bbi
cikben sz疣d駝ozok visszat駻ni a m?g?ttes m?k?d駸i mechanizmus ismertet駸駻e 駸 az ?gy megnyil? plussz
lehet?s馮ek bemutat疽疵a.
Kiss チrp疆