PYTHON C++混合编程笔记(一)- VS2017 编译 python 2.7
0x00 前言
最近想把一些经验和笔记分享出来,也便于自己查询和复习。
0x01 环境准备
1) 下载python 最新2.7.16源代码
https://www.python.org/ftp/python/2.7.16/Python-2.7.16.tar.xz
2) VS2017
0x02 外部库下载
1)命令行进入到解压目录的PCbuild,如X:\Python-2.7.16\PCbuild
2)运行get_externals.bat,下载外部库,如图所示
0x03 编译
1)打开PCbuild目录的pcbuild.sln,根据需要选择后点“确定”,如图所示:
2)先选择python、pythoncore的win32 debug 版本测试编译,如图所示:
3)编译失败,需要修改相关标识符
4)timezone改为_timezone , daylight改为daylight , tzname改为tzname后,重新编译
1 #ifdef PYOS_OS2 2 PyModule_AddIntConstant(m, "timezone", _timezone); 3 #else /* !PYOS_OS2 */ 4 PyModule_AddIntConstant(m, "timezone", _timezone); 5 #endif /* PYOS_OS2 */ 6 #ifdef HAVE_ALTZONE 7 PyModule_AddIntConstant(m, "altzone", altzone); 8 #else 9 #ifdef PYOS_OS2 10 PyModule_AddIntConstant(m, "altzone", _timezone-3600); 11 #else /* !PYOS_OS2 */ 12 PyModule_AddIntConstant(m, "altzone", _timezone -3600); 13 #endif /* PYOS_OS2 */ 14 #endif 15 PyModule_AddIntConstant(m, "daylight", _daylight); 16 PyModule_AddObject(m, "tzname", 17 Py_BuildValue("(zz)", _tzname[0], _tzname[1]));
5)编译仍然失败,如下图所示:
6)找到pythoncore 工程的posixmodule.c , 修改_PyVerify_fd如下
/* This function emulates what the windows CRT does to validate file handles */ int _PyVerify_fd(int fd) { // const int i1 = fd >> IOINFO_L2E; // const int i2 = fd & ((1 << IOINFO_L2E) - 1); // static int sizeof_ioinfo = 0; // /* Determine the actual size of the ioinfo structure, // * as used by the CRT loaded in memory // */ // if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) { // sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS; // } // if (sizeof_ioinfo == 0) { // /* This should not happen... */ // goto fail; // } // /* See that it isn't a special CLEAR fileno */ // if (fd != _NO_CONSOLE_FILENO) { // /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead // * we check pointer validity and other info // */ // if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) { // /* finally, check that the file is open */ // my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo); // if (info->osfile & FOPEN) { // return 1; // } // } // } //fail: // errno = EBADF; //a call to _get_osfhandle with invalid fd sets errno to EBADF if (_get_osfhandle(fd) == INVALID_HANDLE_VALUE) return 0; else return 1; return 0; }
7)再次编译,编译成功。
8)根据需要选择相应库进行编译
0x04 后记
C++ 调用python的工程中, 如果是debug必须使用debug版本的python,如果是release必须使用release版本编译的python,包括所有库的lib,debug必须使用***_d.lib。