使用Nuitka编译Pygame程序报错SystemError: null argument to internal routine
问题
使用Nuitka编译基于Pygame的Python程序时,运行编译后的程序出现错误:SystemError: null argument to internal routine,但PyInstaller编译该程序可正常运行。
程序代码
import os os.environ["PYGAME_HIDE_SUPPORT_PROMPT"]="" import sys import pygame import time import ctypes pygame.init() info = pygame.display.Info() window_size = (info.current_w, info.current_h) screen = pygame.display.set_mode((0,0), pygame.FULLSCREEN, pygame.NOFRAME, pygame.SWSURFACE) pygame.display.set_caption("") hwnd = pygame.display.get_wm_info()["window"] ctypes.windll.user32.SetForegroundWindow(hwnd) ctypes.windll.user32.SetWindowPos(hwnd, -1, 0, 0, 0, 0, 0x0003) ctypes.windll.user32.SetWindowLongW(hwnd, -20, ctypes.windll.user32.GetWindowLongW(hwnd, -20) | 0x80) font = pygame.font.SysFont('SimHei', 50) color = (255, 255, 255) alpha = 0 text_list = ["Text 1", "Text 2", "Text 3", "Text 4"] current_text_index = 0 fade_in_time = 1 fade_out_time = 1 show_time = 5 start_time = time.time() clock = pygame.time.Clock() FPS = 60 game_running = True num = 0 while True: if text_list[current_text_index] == text_list[(len(text_list)-1)]: num += 1 if num == FPS*(show_time-fade_in_time-fade_out_time): game_running = False for event in pygame.event.get(): if event.type == pygame.QUIT: pass current_time = time.time() elapsed_time = current_time - start_time if elapsed_time >= show_time: current_text_index += 1 if current_text_index >= len(text_list): current_text_index = 0 start_time = time.time() if elapsed_time < fade_in_time: alpha = int(255 * (elapsed_time / fade_in_time)) elif elapsed_time > (show_time - fade_out_time) and game_running == True: alpha = int(255 * ((show_time - elapsed_time) / fade_out_time)) else: alpha = 255 screen.fill((0, 0, 0)) text_surface = font.render(text_list[current_text_index], True, color) text_surface.set_alpha(alpha) screen.blit(text_surface, ((window_size[0]-text_surface.get_width())/2, (window_size[1]-text_surface.get_height())/2)) if game_running: pygame.display.flip() clock.tick_busy_loop(FPS) else: if event.type == pygame.KEYDOWN: break pygame.quit() sys.exit()
编译命令
python -m nuitka --onefile --standalone --follow-imports --include-package=pygame,ctypes,os F:\encrypt\draw.py
环境信息
- Nuitka版本:1.5.1
- Python版本:3.10.5(64位Windows版本)
- 操作系统:Windows 10
- C编译器:gcc 11.3.0
解决思路与方案
1. 修复事件循环逻辑漏洞
原代码中else块内的event.type访问存在未定义风险,当game_running为False时,event变量可能未被初始化,触发空参数错误。修改事件处理逻辑,统一在全局循环中处理退出事件:
while game_running: if text_list[current_text_index] == text_list[-1]: num += 1 if num == FPS*(show_time-fade_in_time-fade_out_time): game_running = False # 全局处理所有事件 for event in pygame.event.get(): if event.type == pygame.QUIT: game_running = False if event.type == pygame.KEYDOWN: game_running = False # 剩余原有逻辑保持不变...
2. 增加窗口句柄空值校验
在调用ctypes系统函数前,确保hwnd不为空,避免传递空参数触发内部错误:
hwnd = pygame.display.get_wm_info().get("window") if hwnd: ctypes.windll.user32.SetForegroundWindow(hwnd) ctypes.windll.user32.SetWindowPos(hwnd, -1, 0, 0, 0, 0, 0x0003) style = ctypes.windll.user32.GetWindowLongW(hwnd, -20) ctypes.windll.user32.SetWindowLongW(hwnd, -20, style | 0x80)
3. 调整Nuitka编译参数
原参数过度包含标准库,且未指定Pygame字体资源路径,修改为:
python -m nuitka --onefile --standalone --include-data-dir="%USERPROFILE%\AppData\Local\Programs\Python\Python310\Lib\site-packages\pygame\fonts=pygame/fonts" --include-package=pygame --windows-disable-console F:\encrypt\draw.py
- 新增
--include-data-dir确保编译后能加载SimHei字体 - 移除不必要的标准库
ctypes,os的--include-package配置 - 去掉
--follow-imports,避免引入冗余依赖
4. 升级Nuitka版本
当前使用的1.5.1版本存在Python 3.10与Pygame的兼容问题,升级到最新稳定版本可修复已知编译错误:
pip install --upgrade nuitka
内容的提问来源于stack exchange,提问作者Sheikh Jones
相关产品推荐
相关产品推荐

