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

20 篇文章 6 订阅

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

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值