记录一下将 pygame -> nintendo switch 中遇到的坑
为 renpy -> nintendo switch 做前置工作 ( renpy 构建在 pygame_sdl2 之上 )
---
1. 大部分主机平台不提供 dlopen 等动态库函数,所以你必须把需要的 c 语言库编译成.a (archieve file), 然后用 PyImport_Inittab 的方式注册到 builtin-module 中,然后通过 builtin-importer 导入
2. builtin-module 不能包含 package ( 你不能通过 PyImport_Inittab("a.b", PyInit_b); 注册一个 a.b 的 builtin-module 到 cpython,只能是 PyImport_Inittab("b", PyInit_b)),但大多数编译的库都是包含在一个 package 中的,例如 a.b,这就需要一些 hack 技巧
定制化一个 Importer,该 Importer 将所有的调用 forward 到 BuiltinImporter ( 除了 find_spec 函数, 这个函数中将 a.b 转换成注册到 PyImport_Inittab 里的名字,在这里也就是 b )
---
代码
class SailingImporter: # legacy @staticmethod def module_repr(module): print("SailingImporter module_repr " + str(module)) return BuiltinImporter.module_repr(module) @classmethod def find_spec(cls, fullname , path , target): if 'pygame_sdl2.' in str(fullname): fullname = fullname[len('pygame_sdl2.'):] print("SailingImporter find_spec " + str(fullname) + " " + str(path) + " " + str(target)) # return BuiltinImporter.find_spec(fullname, path, target) return spec_from_loader(fullname, BuiltinImporter) # legacy @classmethod def find_module(cls, fullname, path=None): print("SailingImporter find_module " + str(cls) + " " + str(fullname) + " " + str(path)) return importlib.machinery.BuiltinImporter.find_module(fullname=fullname, path=path) @staticmethod def create_module(spec): print("SailingImporter create_module " + str(spec)) # return BuiltinImporter.create_module(spec) return _call_with_frames_removed(_imp.create_builtin, spec) @staticmethod def exec_module(module): print("SailingImporter exec_module " + str(module)) return BuiltinImporter.exec_module(module) @classmethod def get_code(cls, fullname): return None @classmethod def get_source(cls, fullname): pass @classmethod def is_package(cls, fullname): return False # !! sys.meta_path.append(SailingImporter)
---
switch 运行 pygame 截图 ( hello world )
---
暂无关于此日志的评论。