我正在使用Python 3.6在Windows上工作。我有以下用于测试python解释器的简单死代码:

Py_SetProgramName(L"MyApp");

Py_SetPath(
    L"C:\\Users\\rutski\\Documents\\python\\PCBuild\\amd64\\python36.zip;"
    L"C:\\Users\\rutski\\Documents\\python\\DLLs;"
    L"C:\\Users\\rutski\\Documents\\python\\lib;"
    L"C:\\Users\\rutski\\Documents\\python\\PCBuild\\amd64;"
    L"C:\\Users\\rutski\\Documents\\python;"
    L"C:\\Users\\rutski\\Documents\\python\\lib\\site-packages");

Py_Initialize();

PyRun_SimpleString(
    "from time import time,ctime\n"
    "print('Today is', ctime(time()))\n");

尝试从PyRun_SimpleString()中访问地址0x00000010时,此代码崩溃。事件的顺序是这样的:
  • PyRun_SimpleString()确实执行AddModule(“__ main__”)
  • AddModule执行PyImport_GetModuleDict()
  • PyImport_GetModuleDict()尝试做doPyThreadState_GET()-> interp
  • PyThreadState_GET()返回NULL,因此-> interp部分崩溃。

  • 奇怪的是,从我的应用程序内直接调用PyImport_GetModuleDict()可以正常工作。奇怪的是,如果我使用main()中的嵌入代码构建Windows命令行应用程序,并从终端执行它,则整个程序实际上执行正常。仅当构建Windows GUI应用程序并调用WinMain()中的嵌入代码时,才会发生崩溃。

    这是我使用PCbuild\build.bat在Windows上从源代码构建的python解释器,以便可以跟踪崩溃。但是,我使用PCbuild\build.bat在Windows上从源代码构建的python windows installer.er提供的股票解释器发生了完全相同的崩溃,以便我可以跟踪崩溃。但是,python Windows安装程序提供的股票解释器发生了完全相同的崩溃。

    一个相关的帖子似乎在这里:Embedding Python, works in main() but not in WinMain()

    尽管该线程尚未解决,但是无论如何它并没有以完全相同的方式崩溃。也许这仅仅是由于它们在3.4上,而我在3.6上。也许潜在的问题是相同的。

    最佳答案

    在黑暗中much绊绊之后,我有了答案。下表显示了我将WinMain()应用程序的不同构建配置与不同的python库配对时执行的测试结果。术语“发布”和“调试”是指Visual Studio中的配置类型。所有构建均以x64模式完成。

    Debug   | python36.lib   | Works
    Debug   | python36_d.lib | Works
    Debug   | python3_d.lib  | Works
    Debug   | python3.lib    | !!! CRASHES !!!
    Release | python36.lib   | Works
    Release | python36_d.lib | Works
    Release | python3_d.lib  | !!! CRASHES !!!
    Release | python3.lib    | Works
    

    因此,似乎是这样的情况:选择不匹配的python二进制文件会导致崩溃,但仅适用于python3,而不适用于python36 。这让我想知道两者之间的区别是什么。我之所以开始崩溃,是因为我将Debug版本与发行版本python3.lib链接在一起,因为我认为这无关紧要。

    我的问题现在已经解决,但是如果有人可以阐明为什么会发生的细节,那么我肯定会感兴趣。

    10-04 23:32
    查看更多