2017/09/03(日) [n年前の日記]
#1 [python][windows][pi3d] Windows10 x64上に pi3d をインストールしてみたり
Windows上でも
_pi3d
はインストールできるらしいので試してみた。
_Introduction to pi3d - pi3d 2.20 documentation
環境は Windows10 x64 + Python 2.7.13 or Python 3.5.4。
_Introduction to pi3d - pi3d 2.20 documentation
環境は Windows10 x64 + Python 2.7.13 or Python 3.5.4。
> python --version Python 2.7.13 > py -2 --version Python 2.7.13 > py -3 --version Python 3.5.4
◎ 動作に必要なモジュールをインストール。 :
pi3dをWindows上で動かすには以下のモジュールも必要になるらしい。
現時点では pip でインストールできる。
最後に pi3d をインストール。
pygame Pillow numpy
現時点では pip でインストールできる。
pip install pygame pip install Pillow pip install numpy
最後に pi3d をインストール。
pip install pi3d
pip listと打てばインストール済みモジュールの一覧が表示されるので、インストールできたか確認できるはず。
◎ デモスクリプト群 pi3d_demos を入手。 :
_pi3d/pi3d_demos: Demos and support files for pi3d
git を使って持ってくる。
あるいは、zipをダウンロードして解凍してもいい。 _pi3d/pi3d_demos の、右上のほうの緑のボタン、「Clone or download」→「Download zip」をクリックすれば、zipファイルとしてダウンロードできる。
git を使って持ってくる。
git clone https://github.com/pi3d/pi3d_demos.git
あるいは、zipをダウンロードして解凍してもいい。 _pi3d/pi3d_demos の、右上のほうの緑のボタン、「Clone or download」→「Download zip」をクリックすれば、zipファイルとしてダウンロードできる。
◎ ANGLEの入手。 :
pi3dをWindows上で動かすためには、OpenGL ES をエミュレートするANGLEなるものが ―― 3〜4ファイルの .dllファイルが必要になるらしい。
入手方法はいくつかあるようで。
その1。 _paddywwoof/pi3d_windll からzipでダウンロードして解凍。中に入ってる dllファイルを使わせてもらう方法。
その2。Mozilla Firefox のインストールフォルダ、
その3。Google Chrome のインストールフォルダ、
動作に必要なファイルは3〜4ファイル。
これらのファイルを、動かしたいスクリプトと同じ階層に置く。例えば pi3d_demos を動かしたいなら、pi3d_demosフォルダの中にコピーする。
Pythonが32bit版なら、32bit版用のdllを、Pythonが64bit版なら、64bit版のdllを用意する。
ちなみに自分の環境では、 _paddywwoof/pi3d_windll の32bit版dll、あるいは Firefoxのソレが使えて、Google Chromeのソレは使えなかった。
入手方法はいくつかあるようで。
その1。 _paddywwoof/pi3d_windll からzipでダウンロードして解凍。中に入ってる dllファイルを使わせてもらう方法。
その2。Mozilla Firefox のインストールフォルダ、
C:\Program Files (x86)\Mozilla Firefox\から、該当する .dll をコピーしてくる方法。
その3。Google Chrome のインストールフォルダ、
C:\Program Files (x86)\Google\Chrome\Application\バージョン番号\からコピーしてくる方法。
動作に必要なファイルは3〜4ファイル。
libegl.dll libglesv2.dll d3dcompiler_47.dll # 最後の数字は違ってる可能性有 mozglue.dll # Mozilla Firefox のみ必要
これらのファイルを、動かしたいスクリプトと同じ階層に置く。例えば pi3d_demos を動かしたいなら、pi3d_demosフォルダの中にコピーする。
Pythonが32bit版なら、32bit版用のdllを、Pythonが64bit版なら、64bit版のdllを用意する。
ちなみに自分の環境では、 _paddywwoof/pi3d_windll の32bit版dll、あるいは Firefoxのソレが使えて、Google Chromeのソレは使えなかった。
◎ デモスクリプトの実行。 :
pi3d_demos の Earth.py を動かしてみる。
ところが。Python 3.5 ならどうか。
どうやら現時点では、Windows + Python + pi3d は、 Python 3.x でしか動かないようだなと。
cd pi3d_demos python Earth.py
D:\home\prg\python\_test_sample\pi3d\pi3d_demos\pi3d_demos> python Earth.py Traceback (most recent call last): File "Earth.py", line 11, in <module> import pi3d File "C:\Python\Python27\lib\site-packages\pi3d\__init__.py", line 10, in <module> from pi3d.constants import * File "C:\Python\Python27\lib\site-packages\pi3d\constants\__init__.py", line 167, in <module> PLATFORM, bcm, openegl, opengles = _detect_platform_and_load_libraries() File "C:\Python\Python27\lib\site-packages\pi3d\constants\__init__.py", line 160, in _detect_platform_and_load_libraries platform, bcm, openegl, opengles = loader() File "C:\Python\Python27\lib\site-packages\pi3d\constants\__init__.py", line 139, in _windows opengles = _load_library("libglesv2.dll", "Win") File "C:\Python\Python27\lib\site-packages\pi3d\constants\__init__.py", line 77, in _load_library Log.logger(__name__).error("Couldn't load library %s", name) AttributeError: 'module' object has no attribute 'logger'Python 2.7 上で試したらエラーが出て動かない…。libglesv2.dll を見つけ出すところで処理に失敗してる模様。
ところが。Python 3.5 ならどうか。
> py -3 Earth.pyこっちだと動いてしまった。地球と月がWindows上でもクルクル回ってる。
どうやら現時点では、Windows + Python + pi3d は、 Python 3.x でしか動かないようだなと。
◎ どうしてエラーが出るのか謎。 :
Python 2.7で動かそうとした場合、
_pi3d/constants/__init__.py
でエラーが出るわけだけど。ソースを眺めても、これでどうしてエラーが出るのか分からない。
pi3d_demosフォルダ内に _mydemo.py というファイルを作って動作確認してみた。
__mydemo.py
なのに、pi3d/constants/__init__.py を呼び出すとエラーになってしまう。何故? どうして?
もし、Python 2.7同梱の ctypes のバグだったら、どっちもエラーが出るはずだよな…。なのに、片方はエラーで、片方は動く…。
Python 3.5 では動いてしまうのも謎。何故。
pi3d_demosフォルダ内に _mydemo.py というファイルを作って動作確認してみた。
__mydemo.py
import sys # sys.path.insert(1, '/home/pi/pi3d') import ctypes def _load_library(name, dll_type="C"): if name: try: if dll_type == "Win": return ctypes.WinDLL(name) else: return ctypes.CDLL(name) except: print("Couldn't load library %s" % name) opengles = _load_library("libglesv2.dll", "Win") openegl = _load_library("libegl.dll", "Win") print(opengles) print(openegl)
> python _mydemo.py <WinDLL 'libglesv2.dll', handle 5ae30000 at 3467cd0> <WinDLL 'libegl.dll', handle 5daa0000 at 3467db0>ちゃんとdllを見つけることができてる。pi3d/constants/__init__.py をコピペして動かしてみたのに問題が出ていない。
なのに、pi3d/constants/__init__.py を呼び出すとエラーになってしまう。何故? どうして?
もし、Python 2.7同梱の ctypes のバグだったら、どっちもエラーが出るはずだよな…。なのに、片方はエラーで、片方は動く…。
Python 3.5 では動いてしまうのも謎。何故。
◎ エラーが出る原因が分かった。 :
Python 2.7.13 のバグらしい。
_TypeError: LoadLibrary() argument 1 must be string, not unicode - Issue #147 - carlosperate/ardublockly
_Issue 29082: In 2.7.13, _ctypes.LoadLibrary no longer accepts Unicode objects - Python tracker
_ctypes - TypeError when importing ghostscript on Python - Stack Overflow
ctypes.WinDLL() に渡すべき文字列の種類が、Python 2.7.13 と Python 3.x では違ってしまっているらしい。Unicode文字列だか、バイト文字列だか…。
例えば、pi3d/constants/__init__.py の _load_library() を、以下のように書き換えるとエラーメッセージが変わってくる。
Python 2.7.13 で動かした場合。
Python 2.7.13 で動くように修正してみると…。
しかし、同じ修正をしたものを Python 3.5.4 で動かしてみると。
Python 2.7.13 と Python 3.5.4 で、エラーメッセージが違ってる…。LoadLibrary() に与えるべき文字列の種類が違うという。
解決策としては…。英語圏のやり取りを眺めると「Python 2.7.12 にダウングレードしろ」「もしくは Python 3.x を使え」ということになってるっぽいな…。
Python 2.7.13 は _結構色々修正されてる っぽいから、できれば 2.7.13 のほうがいいのではと思えてくるけど、しかし、こういう不具合があるのでは…。ていうか去年の年末に報告されてたのに、修正版はまだ出ないのか…。
_TypeError: LoadLibrary() argument 1 must be string, not unicode - Issue #147 - carlosperate/ardublockly
_Issue 29082: In 2.7.13, _ctypes.LoadLibrary no longer accepts Unicode objects - Python tracker
_ctypes - TypeError when importing ghostscript on Python - Stack Overflow
ctypes.WinDLL() に渡すべき文字列の種類が、Python 2.7.13 と Python 3.x では違ってしまっているらしい。Unicode文字列だか、バイト文字列だか…。
例えば、pi3d/constants/__init__.py の _load_library() を、以下のように書き換えるとエラーメッセージが変わってくる。
def _load_library(name, dll_type="C"): """Try to load a shared library, report an error on failure.""" if name: try: if dll_type == "Win": return ctypes.WinDLL(name) else: return ctypes.CDLL(name) except: from pi3d.util import Log Log.logger(__name__).error("Couldn't load library %s", name)↓
def _load_library(name, dll_type="C"): """Try to load a shared library, report an error on failure.""" if name: if dll_type == "Win": return ctypes.WinDLL(name) else: return ctypes.CDLL(name)
Python 2.7.13 で動かした場合。
> python Earth.py Traceback (most recent call last): File "Earth.py", line 11, in <module> import pi3d (中略) File "C:\Python\Python27\lib\site-packages\pi3d\constants\__init__.py", line 72, in _load_library return ctypes.WinDLL(name) File "C:\Python\Python27\lib\ctypes\__init__.py", line 362, in __init__ self._handle = _dlopen(self._name, mode) TypeError: LoadLibrary() argument 1 must be string, not unicode「TypeError: LoadLibrary() argument 1 must be string, not unicode」と怒られてる。
Python 2.7.13 で動くように修正してみると…。
def _load_library(name, dll_type="C"): """Try to load a shared library, report an error on failure.""" if name: name = name.encode('ascii', 'ignore') # add if dll_type == "Win": return ctypes.WinDLL(name) else: return ctypes.CDLL(name)1行追加しただけで、Python 2.7.13 でも動くようになった。
しかし、同じ修正をしたものを Python 3.5.4 で動かしてみると。
> py -3 Earth.py Traceback (most recent call last): File "Earth.py", line 11, in <module> import pi3d (中略) File "C:\Python\Python35\lib\site-packages\pi3d\constants\__init__.py", line 72, in _load_library return ctypes.WinDLL(name) File "C:\Python\Python35\lib\ctypes\__init__.py", line 351, in __init__ self._handle = _dlopen(self._name, mode) TypeError: LoadLibrary() argument 1 must be str, not bytes今度は、「TypeError: LoadLibrary() argument 1 must be str, not bytes」と怒られた。
Python 2.7.13 と Python 3.5.4 で、エラーメッセージが違ってる…。LoadLibrary() に与えるべき文字列の種類が違うという。
TypeError: LoadLibrary() argument 1 must be string, not unicode TypeError: LoadLibrary() argument 1 must be str, not bytes
解決策としては…。英語圏のやり取りを眺めると「Python 2.7.12 にダウングレードしろ」「もしくは Python 3.x を使え」ということになってるっぽいな…。
Python 2.7.13 は _結構色々修正されてる っぽいから、できれば 2.7.13 のほうがいいのではと思えてくるけど、しかし、こういう不具合があるのでは…。ていうか去年の年末に報告されてたのに、修正版はまだ出ないのか…。
[ ツッコむ ]
以上です。