Google AdSense

2014年12月26日 星期五

修理在 PyPy3 使用 PySDL2 import sdl2.ext 時會當掉的問題

說明

  • 在 PyPy3 下使用 PySDL2 時,只要嘗試 import sdl2.ext,PyPy3 就會當掉
  • import uuid 時出問題也可能是同樣的原因

解法

  • 問題出在 Pypy3 的 uuid.py 這個檔案。問題程式碼如下:
    try:
        import ctypes, ctypes.util
    
        # The uuid_generate_* routines are provided by libuuid on at least
        # Linux and FreeBSD, and provided by libc on Mac OS X.
        for libname in ['uuid', 'c']:
            try:
                lib = ctypes.CDLL(ctypes.util.find_library(libname))
            except:
                continue
            if hasattr(lib, 'uuid_generate_random'):
                _uuid_generate_random = lib.uuid_generate_random
            if hasattr(lib, 'uuid_generate_time'):
                _uuid_generate_time = lib.uuid_generate_time
    
    問體點在 try 區塊裡。程式本身邏輯是對的,但是 PyPy3 有 bug,當執行
    ctypes.CDLL(None)
    
    時,並不會如預期般的丟出 exception,而是產生訊息
    Fatal RPython error: UnicodeDecodeError
    
    This application has requested the Runtime to terminate it in an unusual way.
    Please contact the application's support team for more information.
    
    並直接當掉,估計這是因為正常的錯誤訊息裡面含有 Unicode 所致。簡單改法如下:
    try:
        import ctypes, ctypes.util
    
        # The uuid_generate_* routines are provided by libuuid on at least
        # Linux and FreeBSD, and provided by libc on Mac OS X.
        for libname in ['uuid', 'c']:
            try:
                name = ctypes.util.find_library(libname)
                if name is None:
                    continue
                lib = ctypes.CDLL(name)
            except:
                continue
            if hasattr(lib, 'uuid_generate_random'):
                _uuid_generate_random = lib.uuid_generate_random
            if hasattr(lib, 'uuid_generate_time'):
                _uuid_generate_time = lib.uuid_generate_time
    
    這並沒有完全解決問題,如果找不到指定的模組,一樣會因為錯誤訊息含有 Unicode 而當掉。如果還是不行的話,嘗試把整個 try except 砍掉吧,這在我的電腦上一樣有用

回顧

  • 其實 PySDL2 也不適合 PyPy,請使用 pysdl2-cffi

沒有留言:

張貼留言