gencache.EnsureModule()
周りを色々調べたついでに備忘録を残します。
EnsureModule()を呼び出す理由
そもそもなんでgencache.EnsureModule()
を呼び出さないといけないかというと、Dispatchする前にearly binding(事前バインディング)したいからなのです。
詳細は以下を参考にします。
- win32com - win32.Dispatch vs win32.gencache in Python. What are the pros and cons? - Stack Overflow
- implement COM interface type library in python - Stack Overflow
Dispatch()
でこれまで使用したことのないCOMオブジェクトを作成しようとすると、Pythonはオブジェクトが何を利用できるかわからないのでエラーが発生します。その場合、EnsureDispatch()
を使うことで事前バインディングになるので、Pythonはオブジェクトが何を利用できるかわかるようになります。
win32.dynamic.Dispatch()
というのもあり、こちらは常にlate binding(遅延バインディング)になるようです。
win32com.client.Dispatch()
で動かない場合はgencache.EnsureModule()
を使うことで、正しくキャッシュモジュールを生成することができます。
EnsureModule()の引数
上記の1個目のサイトを読むと、win32com
の場所を調べると良さそうです。
>>> import win32com >>> win32com.__file__ 'C:\\Users\\XXXX\\AppData\\Local\\Continuum\\anaconda3\\envs\\projectX\\lib\\site-packages\\win32com\\__init__.py' >>>
C:\Users\XXXX\AppData\Local\Continuum\anaconda3\envs\projectX\Lib\site-packages\win32com\client\gencache.py
があったので、EnsureModule()
の実装を見てみます。
def EnsureModule(typelibCLSID, lcid, major, minor, progressInstance = None, bValidateFile=not is_readonly, bForDemand = bForDemandDefault, bBuildHidden = 1): """Ensure Python support is loaded for a type library, generating if necessary. Given the IID, LCID and version information for a type library, check and if necessary (re)generate, then import the necessary support files. If we regenerate the file, there is no way to totally snuff out all instances of the old module in Python, and thus we will regenerate the file more than necessary, unless makepy/genpy is modified accordingly. Returns the Python module. No exceptions are caught during the generate process. Params typelibCLSID -- IID of the type library. major -- Integer major version. minor -- Integer minor version lcid -- Integer LCID for the library. progressInstance -- Instance to use as progress indicator, or None to use the GUI progress bar. bValidateFile -- Whether or not to perform cache validation or not bForDemand -- Should a complete generation happen now, or on demand? bBuildHidden -- Should hidden members/attributes etc be generated? """
lcidはロケールIDだとすると、gencache.EnsureModule('{D98A091D-3A0F-4C3E-B36E-61F62068D488}', 0, 1, 0)
の引数は左から順に、
- クラスID
- ロケールID
- メジャーバージョン番号
- マイナーバージョン番号
ということだと思います。
また、適当にフォルダを適当に漁るとmakepy.pyを見つけることができます。
C:\Users\XXXX\AppData\Local\Continuum\anaconda3\envs\projectX\Lib\site-packages\win32com\client
のmakepy.pyの104-106行目になんか書いてあります。
print(" >>> # Use these commands in Python code to auto generate .py support") print(" >>> from win32com.client import gencache") print(" >>> gencache.EnsureModule('%s', %s, %s, %s)" % (tlbSpec.clsid, tlbSpec.lcid, tlbSpec.major, tlbSpec.minor))
tlbSpecはおそらくキャッシュのTLB(Translation Lookaside Buffer)のことだと思います。なのでおそらく、クラスID等でアプリケーションを指定して、TLBでそのアプリケーションにメモリが割り当てられているといったことをしているのでしょう。