我正在使用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时,此代码崩溃。事件的顺序是这样的:
奇怪的是,从我的应用程序内直接调用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链接在一起,因为我认为这无关紧要。
我的问题现在已经解决,但是如果有人可以阐明为什么会发生的细节,那么我肯定会感兴趣。