VS2008/VS2013 C/C++内嵌python环境 Python编译成EXE

版权声明:版权所有,盗版必究。欢迎转载收藏。 https://blog.csdn.net/yl_best/article/details/80048511

1. 新建一个空的.c或.cpp文件,编写如下code

#include <stdio.h>

int main(int argc, char **argv)
{
	printf("Hello World in C++!\n");
	printf("Press any key to continue……\n");
	getchar();		//wait for your input
	return 0;
}

2. 新建一个Python脚本hello.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-

def HelloWorld():
    print "Hello World in Python!"

if __name__ == "__main__":
    HelloWorld()

3.将Python脚本hello.py嵌入之前的.cpp文件

3.1 在.cpp文件中添加#include <Python.h>

3.2 在.cpp文件中添加一个函数如下

int HelloWorld();

int HelloWorld()
{
	//initialize
	Py_Initialize();

	//if initialization fails, return
	if(!Py_IsInitialized())
	{
		printf("Py_IsInitialized fail");
		return 1;
	}

	//import module whose name is myModule, that is myModule.py
	PyObject *pModule = PyImport_ImportModule("myModule");

	//if it fails, return
	if(!pModule)
	{
		printf("PyImport_ImportModule fail");
		return 2;
	}

	
	//import function - myModule.HelloWorld
	PyObject * pFuncHello = PyObject_GetAttrString(pModule, "HelloWorld");

	//if it fails, return
	if(!pFuncHello)
	{
		printf("PyObject_GetAttrString fail");
		return 3;
	}

	//call function
	PyObject_CallFunction(pFuncHello, NULL);

	//exit python
	Py_Finalize();
	return 0;
}

3.3 main函数调用HelloWorld()函数

#include <stdio.h>
#include <Python.h>

int HelloWorld();

int main(int argc, char **argv)
{
	printf("Hello World in C++!\n");
	HelloWorld();
	printf("Press any key to continue……\n");
	getchar();		//wait for your input
	return 0;
}

int HelloWorld()
{
	//initialize
	Py_Initialize();

	//if initialization fails, return
	if(!Py_IsInitialized())
	{
		printf("Py_IsInitialized fail");
		return 1;
	}

	//import module whose name is myModule, that is myModule.py
	PyObject *pModule = PyImport_ImportModule("myModule");

	//if it fails, return
	if(!pModule)
	{
		printf("PyImport_ImportModule fail");
		return 2;
	}

	
	//import function - myModule.HelloWorld
	PyObject * pFuncHello = PyObject_GetAttrString(pModule, "HelloWorld");

	//if it fails, return
	if(!pFuncHello)
	{
		printf("PyObject_GetAttrString fail");
		return 3;
	}

	//call function
	PyObject_CallFunction(pFuncHello, NULL);

	//exit python
	Py_Finalize();
	return 0;
}

3.4 设置

此时如果按F7 build会fail,错误信息如下

1>正在编译...

1>helloworld.cpp

1>f:\vs_ex\helloworld\helloworld\helloworld.cpp(7) : fatal error C1083: Cannot open include file: 'Python.h': No such file or directory

意思是找不到Python.h文件。这是因为我们没有告诉编译器这个文件在哪

解决办法如下:

3.4.1 右击项目->属性,或者在菜单栏“项目->helloworld属性(ALT+F7)”

进入如下属性对话框

3.4.2 VS(Visual Studio)工程属性设置

在Additional Include Directories(附加包含目录)里添上C:\Python27\include\

,在Additional Library Directories(附加库目录)里添上C:\Python27\libs,其中C:\Python27是我的python安装目录;

做完这些之后,就可以在.cpp里#include <Python.h>

3.4.3 build时又出现错误

fatal error LNK1104: cannot open file 'python27_d.lib'

具体原因请参考另外一篇文章

C++调用Python Build出错cannot open file 'python27_d.lib'

解决办法:请将C:/Python27/libs下的python27.lib复制一份改名为python27_d.lib(其中C:\Python27是我的python安装目录

若编译Debug版,也要做如此操作。

4. 执行结果

5.结论&总结

从上述代码可以窥见Python内部运行的方式:

5.1 调用Python必须要使用的两个函数Py_Initialize();Py_Finalize();。其中Py_Initialize()无返回值,需要检查这个参数Py_IsInitialized()来确认是否有初始化成功。

5.2 python有明确说,Py_Finalize并不能释放所有的内存,特别是扩展模块内存。(看相关的英文手册)。多次反复调用,必然有问题。

参看Python文档http://docs.python.org/c-api/init.html
void Py_Finalize()
Bugs and caveats: The destruction of modules and objects in modules is done in random order; this may cause destructors (__del__() methods) to fail when they depend on other objects (even functions) or modules. Dynamically loaded extension modules loaded by Python are not unloaded. Small amounts of memory allocated by the Python interpreter may not be freed (if you find a leak, please report it). Memory tied up in circular references between objects is not freed. Some memory allocated by extension modules may not be freed. Some extensions may not work properly if their initialization routine is called more than once; this can happen if an application calls Py_Initialize() and Py_Finalize() more than once.

5.3所有Python元素,module、function、tuple、string等等,实际上都是PyObject。C语言里操纵它们,一律使用PyObject *。

5.4 Python的类型与C语言类型可以相互转换。Python类型XXX转换为C语言类型YYY要使用PyXXX_AsYYY函数;C类型YYY转换为Python类型XXX要使用PyXXX_FromYYY函数。

5.5也可以创建Python类型的变量,使用PyXXX_New可以创建类型为XXX的变量。

5.6若a是Tuple,则a[i] = b对应于 PyTuple_SetItem(a,i,b),有理由相信还有一个函数PyTuple_GetItem完成取得某一项的值。

5.3-5.6 作者:Jerry Jho
链接:https://www.zhihu.com/question/23003213/answer/56121859

猜你喜欢

转载自blog.csdn.net/yl_best/article/details/80048511