在 C++ 中使用 Python script
来源:互联网 发布:绿坝软件免费下载 编辑:程序博客网 时间:2024/05/01 02:24
http://www.cppblog.com/bigsml/archive/2008/08/14/58859.html
想要在c++ 中嵌入script 代码, 除了自己写脚本引擎外, lua, python 都可以在c++ 中使用, 另外 MonoBind, AngelScript library 都是一些c++ script library, 可以嵌入到c++ 中使用 .
今天在c++ 中试着嵌入 python 代码 (示例代码在 Python-2.5.2/Demo/embed/ 下)
int main(int argc, char *argv[])
{
// Py_NoSiteFlag = 1;
// Py_SetPythonHome("D://usr//Python"); // PYTHONHOME
Py_Initialize();
PyRun_SimpleString("from time import time,ctime/n"
"print 'Today is',ctime(time())/n");
Py_Finalize();
return 0;
}
在运行时可能会产生类似 'import site' failed; use -v for traceback 的错误, 原因是python 在import module 的时候的路径问题. 有3种方法可以解决(以前通过设置环境变量 PYTHONPATH 好像在2.5 已经无效了).
0. 取消注释 Py_NoSiteFlag = 1;
这个只是取消import site , 当然如果在代码中要import 啥的话, 还是会出现错误的.
a. 设置环境变量 PYTHONHOME = D:/usr/Python
b. 在调用 Py_Initialize 之前调用函数
Py_SetPythonHome("D://usr//Python"); // 参数是python 的安装目录
2. 其他一些有用的资源
Python/C API Reference Manual (API 参考) , Extending and Embedding the Python Interpreter (扩展及嵌入Python解释器, 主要说明了如何扩展Python, 给Python 写扩展, 其中 5. Embedding Python in Another Application 一章讲述了在C++中嵌入/调用Python 代码 )
使用C/C++扩展Python 对文 Extending and Embedding the Python Interpreter 作了精简, 很不错的一篇文章, 但是跳过了一些基础 .
Building Hybrid Systems with Boost.Python 介绍了使用boost.python 方便python 插件开发, python绑定c++程序 是其中文版本.
Embedding Python in Multi-Threaded C/C++ Applications 讲了c++在多线程环境如何使用Python , 文 C++多线程中调用python api函数 提供了一个多线程的封装.
SCXX - A Simple Python/C++ API
http://davidf.sjsoft.com/mirrors/mcmillan-inc/scxx.html
C++扩展和嵌入Python应用 (介绍了一些Python/C API 函数, 以及ext 例子, 一般般)
http://hi.baidu.com/yunsweet/blog/item/20b08aeebaa2b1282cf534c7.html
3. Python 多线程的使用
zz http://blog.csdn.net/liguangyi/archive/2007/06/20/1659697.aspx
今天看了近一天关于多线程的应用中,如何安全调用python方面的资料,开始的时候看的简直头大如斗,被python语言的全局锁(Global Interpreter Lock)、线程状态(Thread State )等都有点绕晕了,后来经过各方面文章和帮助文档的相互参考,发现对于2.4/2.5版本,提供了PyGILState_Ensure, PyGILState_Release,哎,这下可方便大发了。
一、首先定义一个封装类,主要是保证PyGILState_Ensure, PyGILState_Release配对使用,而且这个类是可以嵌套使用的。
#include <python.h>
class PyThreadStateLock
{
public:
PyThreadStateLock(void)
{
state = PyGILState_Ensure( );
}
~PyThreadStateLock(void)
{
PyGILState_Release( state );
}
private:
PyGILState_STATE state;
};
二、在主线程中,这样处理
// 初始化
Py_Initialize();
// 初始化线程支持
PyEval_InitThreads();
// 启动子线程前执行,为了释放PyEval_InitThreads获得的全局锁,否则子线程可能无法获取到全局锁。
PyEval_ReleaseThread(PyThreadState_Get());
// 其他的处理,如启动子线程等
......
// 保证子线程调用都结束后
PyGILState_Ensure();
Py_Finalize();
// 之后不能再调用任何python的API
三、在主线程,或者子线程中,调用python本身函数的都采用如下处理
{
class PyThreadStateLock PyThreadLock;
// 调用python的API函数处理
......
}
呵呵,看这样是否非常简单了。
另外还有两个和全局锁有关的宏,Py_BEGIN_ALLOW_THREADS 和 Py_END_ALLOW_THREADS。这两个宏是为了在较长时间的C函数调用前,临时释放全局锁,完成后重新获取全局锁,以避免阻塞其他python的线程继续运行。这两个宏可以这样调用
{
class PyThreadStateLock PyThreadLock;
// 调用python的API函数处理
......
Py_BEGIN_ALLOW_THREADS
// 调用需要长时间的C函数
......
Py_END_ALLOW_THREADS
// 调用python的API函数处理
......
}
4. 可能的错误及解决
a. 在vs 200x 下 debug 模式出现链接问题
extmodule.obj : error LNK2019: unresolved external symbol __imp___Py_Dealloc referenced in function _PySwigObject_format
extmodule.obj : error LNK2019: unresolved external symbol __imp___Py_NegativeRefcount referenced in function _PySwigObject_format
extmodule.obj : error LNK2001: unresolved external symbol __imp___Py_RefTotal
extmodule.obj : error LNK2019: unresolved external symbol __imp___PyObject_DebugFree referenced in function _PySwigObject_dealloc
extmodule.obj : error LNK2019: unresolved external symbol __imp___PyObject_DebugMalloc referenced in function _PySwigObject_New
extmodule.obj : error LNK2019: unresolved external symbol __imp__Py_InitModule4TraceRefs referenced in function _init_extmodule
主要是因为 Py_DEBUG/Py_TRACE_REFS 引起, 修改 Python/include 下的 pyconfig.h, object.h 两个文件就行了 ... 详见 http://www.nabble.com/link-error-in-debug-mode-td3126668.html
- 在 C++ 中使用 Python script
- 在 C++ 中使用 Python script
- 在<script></script>标签中一样可以使用el表达式
- 在HTML中使用<script>做模板
- 在Python中调用C++,使用SWIG
- 在Python中使用C程序
- Python Flask script 使用
- [Python] modify *.c -> *.java script
- script 中使用 trap
- SAP ABAP/4学习---在SCRIPT中使用图片
- 在VS2005中使用回调(Script Callback)
- 在qtp中使用vb script 实现写文件功能
- 如何使用 Microsoft Script Edit 在 J2EE 中调试 JAVASCRIPT
- 在powerdesigner中使用vb script 创建index
- 在Java中使用脚本语言 javax.script探秘
- 第2章 在 HTML 中使用 JavaScript <script>元素
- Revit中Dynamo编程——在Python Script中引用Python的py文件
- 在python中使用C语言 [Linux Ubuntu]
- 事务隔离级别和锁
- java初始化时区
- 文件操作
- 事务具有4个属性
- C++ 扩展和嵌入 Python
- 在 C++ 中使用 Python script
- 拙著《J2ME手机高级编程》新近上架
- Boost Python 介绍
- 使用C/C++扩展Python
- 链接错误nafxcwd.lib(afxmem.obj) : error LNK2005: "void __cdecl operator delete(void *)" (??3@YAXPAX@Z) already defined in libcpd
- Boost python 学习笔记
- VBA中调用Notes
- 电脑保护色
- 使用 Boost.Python 嵌入 Python 模块到 C++