bzz*_*zzr 7 c windows tkinter python-embedding python-3.5
我的项目结构如下所示:
emb
| CMakeLists.txt
| main.c
| python35.lib
| stdlib.zip
| _tkinter.pyd
|
+---include
| |
| | abstract.h
| | accu.h
| | asdl.h
...
| | warnings.h
| | weakrefobject.h
|
+---build
| | emb.exe
Run Code Online (Sandbox Code Playgroud)
stdlib.zip包含Python 3.5.2安装中的DLL,Lib和site-packages目录,其路径被追加到sys.path.我通过链接到python35.lib隐式加载python35.dll,python35.lib包含DLL中所有导出函数的存根.这是CMakeLists.txt的内容:
cmake_minimum_required(VERSION 3.6)
project(embpython)
set(SOURCE_FILES main.c)
add_executable(${PROJECT_NAME} ${SOURCE_FILES})
set(PYTHON_INCLUDE_DIR include)
include_directories(${PYTHON_INCLUDE_DIR})
target_link_libraries(
${PROJECT_NAME}
${CMAKE_CURRENT_LIST_DIR}/python35.lib
${CMAKE_CURRENT_LIST_DIR}/_tkinter.pyd)
Run Code Online (Sandbox Code Playgroud)
这是main.c的内容:
#include <Python.h>
int main(int argc, char** argv)
{
wchar_t* program_name;
wchar_t* sys_path;
char* path;
program_name = Py_DecodeLocale(argv[0], NULL);
if (program_name == NULL)
{
fprintf(stderr, "Fatal error: cannot decode argv[0]\n");
exit(1);
}
Py_SetProgramName(program_name);
path = "stdlib.zip;stdlib.zip/DLLs;stdlib.zip/Lib;"
"stdlib.zip/site-packages";
sys_path = Py_DecodeLocale(path, NULL);
Py_SetPath(sys_path);
Py_Initialize();
PySys_SetArgv(argc, argv);
PyRun_SimpleString("import tkinter\n");
Py_Finalize();
PyMem_RawFree(sys_path);
PyMem_RawFree(program_name);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
现在,这是我得到的错误:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File " ... emb\stdlib.zip\Lib\tkinter\__init__.py", line 35, in <module>
ImportError: DLL load failed: The specified module could not be found.
Run Code Online (Sandbox Code Playgroud)
我做错了什么,我该如何解决?
这个答案并不意味着是嵌入带有 Tkinter 支持的 Python 3.5 的正确或最佳方法。分步格式仅反映了这样一个事实:这就是我设法让所有内容在我的计算机上运行的方式,并且由于我无法在其他地方测试此解决方案,因此我无法确认它是否适用于所有甚至大多数情况。
\n\n在src中创建main.py文件其中包含以下内容:
\n\nimport tkinter as tk\n\ndef run():\n root = tk.Tk()\n root.mainloop()\nRun Code Online (Sandbox Code Playgroud)在src中创建一个main.c文件其中包含以下内容:
\n\n// WARNING: I did not check for errors but you definitely should!\n\n#import <Python.h>\n\nstatic const char* SYS_PATH = "source.zip;stdlib.zip;lib/python35";\n\nint main(int argc, char** argv)\n{\n wchar_t* program = NULL;\n wchar_t** wargv = NULL;\n wchar_t* sys_path = NULL;\n int i;\n\n program = Py_DecodeLocale(argv[0], NULL);\n Py_SetProgramName(program);\n\n sys_path = Py_DecodeLocale(SYS_PATH, NULL);\n Py_SetPath(sys_path);\n\n Py_Initialize();\n\n wargv = (wchar_t**) malloc(argc * sizeof(wchar_t*));\n for (i = 0; i < argc; i++)\n wargv[i] = Py_DecodeLocale(argv[i], NULL);\n PySys_SetArgv(argc, wargv);\n\n PyRun_SimpleString("import main\\n"\n "main.run()\\n");\n\n Py_Finalize();\n PyMem_RawFree(program);\n PyMem_RawFree(sys_path);\n for (i = 0; i < argc; i++)\n PyMem_RawFree(wargv[i]);\n free(wargv);\n return 0;\n}\nRun Code Online (Sandbox Code Playgroud)创建CMakeLists.txt文件,内容如下:
\n\ncmake_minimum_required(VERSION 3.6)\nproject(emb)\n\nset(SOURCE_FILES src/main.c)\nadd_executable(emb ${SOURCE_FILES})\n\ninclude_directories(include)\n\nadd_library(libpython35 STATIC IMPORTED)\nset_property(\n TARGET libpython35 PROPERTY IMPORTED_LOCATION\n ${CMAKE_CURRENT_LIST_DIR}/lib/libpython35.a)\n\ntarget_link_libraries(emb libpython35)\nRun Code Online (Sandbox Code Playgroud)构建并运行。如果到目前为止您所做的一切都是正确的,您应该会看到如下内容:
\n\nTraceback (most recent call last):\n File "<string>", line 2, in <module>\n File "C:\\path\\to\\project\\stdlib.zip\\tkinter\\__init__.py", line 1868, in __init__\n_tkinter.TclError: Can\'t find a usable init.tcl in the following directories:\n C:/path/to/project/lib/lib/tcl8.6\n C:/path/to/project/lib/tcl8.6 \n C:/path/to/project/library\n C:/path/to/project/tcl8.6.4/library\nRun Code Online (Sandbox Code Playgroud)\n\n找不到 Tcl 和 Tk 目录。我们需要引入它们并更新 TCL_LIBRARY 环境变量。
将tcl8.6和tk8.6目录从C:\\path\\to\\python35\\tcl复制到lib项目根目录下的
创建 TCL_LIBRARY 环境变量并将其设置为"lib\\tcl8.6"。
现在一切都应该正常了。
\n\n\xc2\xb9这并不是绝对必要的。您也可以将 .py 文件保存在一个目录中并将其路径附加到sys.path.
\xc2\xb2 python 引发 before 的原因ImportError是因为_tkinter.pyd位于 zip 文件内,因此无法加载。
| 归档时间: |
|
| 查看次数: |
1399 次 |
| 最近记录: |