- 浏览: 57909 次
- 性别:
- 来自: 广州
最新评论
-
Joson_Coney:
11.
while( (*strDest++ = *strSr ...
c++笔试题汇总 -
Joson_Coney:
③ 1.
int func(x)
{
int countx = ...
c++笔试题汇总 -
Joson_Coney:
链表反向1:
#include <cstdlib&g ...
c++笔试题汇总
(from http://blog.csdn.net/marising/archive/2008/09/12/2917892.aspx, http://blog.csdn.net/marising/archive/2008/09/22/2962322.aspx)
前两篇都是介绍Python调用C++的,换句话说,就是需要把C++封装成Python可以“理解”的类型。这篇,我打算说一下,C++怎么去调用Python脚本。其实这两者之间是相通的,就是需要可以互操作。按照惯例,先贴代码。
test.cpp
view plaincopy to clipboardprint?
#include <python2.6/Python.h>
#include <iostream>
#include <string>
void printDict(PyObject* obj) {
if (!PyDict_Check(obj))
return;
PyObject *k, *keys;
keys = PyDict_Keys(obj);
for (int i = 0; i < PyList_GET_SIZE(keys); i++) {
k = PyList_GET_ITEM(keys, i);
char* c_name = PyString_AsString(k);
printf("%s\n", c_name);
}
}
int main() {
Py_Initialize();
if (!Py_IsInitialized())
return -1;
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./')");
//导入模块
PyObject* pModule = PyImport_ImportModule("testpy");
if (!pModule) {
printf("Cant open python file!\n");
return -1;
}
//模块的字典列表
PyObject* pDict = PyModule_GetDict(pModule);
if (!pDict) {
printf("Cant find dictionary.\n");
return -1;
}
//打印出来看一下
printDict(pDict);
//演示函数调用
PyObject* pFunHi = PyDict_GetItemString(pDict, "sayhi");
PyObject_CallFunction(pFunHi, "s", "lhb");
Py_DECREF(pFunHi);
//演示构造一个Python对象,并调用Class的方法
//获取Second类
PyObject* pClassSecond = PyDict_GetItemString(pDict, "Second");
if (!pClassSecond) {
printf("Cant find second class.\n");
return -1;
}
//获取Person类
PyObject* pClassPerson = PyDict_GetItemString(pDict, "Person");
if (!pClassPerson) {
printf("Cant find person class.\n");
return -1;
}
//构造Second的实例
PyObject* pInstanceSecond = PyInstance_New(pClassSecond, NULL, NULL);
if (!pInstanceSecond) {
printf("Cant create second instance.\n");
return -1;
}
//构造Person的实例
PyObject* pInstancePerson = PyInstance_New(pClassPerson, NULL, NULL);
if (!pInstancePerson) {
printf("Cant find person instance.\n");
return -1;
}
//把person实例传入second的invoke方法
PyObject_CallMethod(pInstanceSecond, "invoke", "O", pInstancePerson);
//释放
Py_DECREF(pInstanceSecond);
Py_DECREF(pInstancePerson);
Py_DECREF(pClassSecond);
Py_DECREF(pClassPerson);
Py_DECREF(pModule);
Py_Finalize();
return 0;
}
编译
g++ test.cpp -o test -lpython2.6
testpy.py
view plaincopy to clipboardprint?
#!/usr/bin/python
# Filename: test.py
class Person:
def sayHi(self):
print 'hi'
class Second:
def invoke(self,obj):
obj.sayHi()
def sayhi(name):
print 'hi',name;
执行
lhb@localhost:~/maplib/clib/pyc/invokepy$ ./test
sayhi
__builtins__
__file__
__package__
Person
Second
__name__
__doc__
hi lhb
hi
我简单解释一下
- 这个例子演示了,创建python中Person类的实例,并作为参数调用Second的方法。
- Py_Initialize()和 Py_Finalize()是初始和销毁Python解释器
- PyRun_SimpleString( "import sys" )导入sys,接着设置py文件的路径PyRun_SimpleString( "sys.path.append('./')" )
- 导入模块PyImport_ImportModule( "testpy" ),就是testpy.py模块。
- 获取模块字典列表,PyModule_GetDict(pModule),可以打印出来看一下如 void printDict(PyObject* obj)函数
- 从字典中获取类的类型 PyDict_GetItemString(pDict, "Second" ),如函数也是这样获取的
- 创造类的实例 PyInstance_New(pClassSecond,NULL,NULL)
- 调用实例的方法PyObject_CallMethod(pInstanceSecond, "invoke" , "O" ,pInstancePerson)
整个流程就是这样的,并不复杂,如果要进一步研究可以参考:http://www.python.org/doc/
比较特殊的是调用Python函数时,参数的传递,就是c++的类型,怎么转换成Python的类型;另外一个问题是,Python函数的返回值,怎么转换成C++中的类型。
C++转换成Python类型,Py_BuildValue()
http://www.python.org/doc/1.5.2p2/ext/buildValue.html
- PyObject* pArgs=PyTuple_New( 1 ); //有几个参数,就是几
- PyTuple_SetItem(pArgs, 0 ,Py_BuildValue( "i" , 3 )); //初始第一个参数,数据类型是i,就是int,值是 3
返回值转换如,PyArg_ParseTuple,请参考
http://www.python.org/doc/1.5.2p2/ext/parseTuple.html
其实,C++调用Python有两种方式,我前面介绍了第一种方式:通过找到Python模块,类,方法,构造参数来调用。第二中方式,就是通过构造出一个Python的脚本,用python引擎来执行。第一种方式可能更为优雅,符合大多数的反射调用的特点。(我在以前的一个项目中,实现了c#的反射机制,c#调用Com+,c#调用javascript脚本等)。
还有一个问题,两种语言互相调用的时候,需要做数据结构(如基本类型,字符串,整数类型等,以及自定义的类等类型)间的转换,共享内存中的一个对象。比如,如何将C++的对象实例传入python中,并在python中使用。c++和python并不在一个进程中,因此可以使用boost的shared_ptr来实现。
下面这个例子,主要是演示了,c++调用python,可以在c++中形成一个python脚本,然后利用PyRun_SimpleString调用;并且,构造一个c++的对象,传入到python中,并在python的脚本中调用其函数。
#include <boost/python.hpp>
#include <iostream>
using namespace boost::python;
class World
{
public:
void set(std::string msg) { this->msg = msg; }
std::string greet() { return msg; }
std::string msg;
};
typedef boost::shared_ptr < World > world_ptr;
BOOST_PYTHON_MODULE(hello)
{
class_ <World>("World")
.def("greet", &World::greet)
.def("set", &World::set)
;
register_ptr_to_python <world_ptr>();
}
int main(int argc, char *argv[])
{
Py_Initialize();
world_ptr worldObjectPtr (new World);
worldObjectPtr->set("Hello from C++!");
try
{
inithello();
PyRun_SimpleString("import hello");
object module(handle <>(borrowed(PyImport_AddModule("__main__"))));
object dictionary = module.attr("__dict__");
dictionary["pyWorldObjectPtr"] = worldObjectPtr;
PyRun_SimpleString("pyWorldObjectPtr.set('Hello from Python!')");
}
catch (error_already_set)
{
PyErr_Print();
}
std::cout << "worldObjectPtr->greet(): " << worldObjectPtr->greet() <<std::endl;
Py_Finalize();
return 0;
}
发表评论
-
【转】Compiling with cython and mingw produces gcc: error: unrecognized command lin
2012-05-03 10:46 1075(From: http://stackoverflow.com ... -
Java Annotation入门
2012-04-17 15:01 0(转自:http://www.blogjava.net/eri ... -
Java:对象的强、软、弱和虚引用
2012-01-09 15:00 567原创作品,允许转载,转载时请务必以超链接形式标明文 ... -
c++笔试题汇总
2011-10-23 16:11 715(转自http://blog.csdn.net/dongfen ... -
c++中使用引用传递来提高效率
2011-10-23 14:37 918(转自:http://www.diybl.com/course ... -
GTK+ 中文显示解决方案
2011-10-15 06:01 667(转自:http://www.wangchao.net.cn/ ... -
Table单元格td的position:relative的兼容性
2011-10-11 12:35 1931( From: http://www.itref.cn/a/ ... -
Remote JSON - JSONP
2011-10-11 12:16 699( From : http://bob.pythonmac.o ... -
GTK+主循环(main loop)的工作原理
2011-10-11 11:59 1115GTK+主循环(main loop)的工作原理 转 ... -
Remote Scripting with IFRAME
2011-10-07 01:24 629( From: http://developer.apple. ... -
Relying on DOM readiness to invoke a function (instead of window.onload)
2011-10-06 06:45 614( From: http://www.javascriptki ... -
Which browsers support HTML5, CSS3, Data URLs, etc.
2011-10-06 06:38 646http://caniuse.com/# -
javascript: negative number "in" array
2011-10-06 06:34 613引用> 3 in [1,2,3,4] true > ... -
The Linux man-pages project
2011-09-30 20:49 490http://www.kernel.org/doc/man-p ... -
【转】Writing Daemons in Javascript with node.JS
2011-09-29 18:19 955April 1, 2010 Writing Daemons ...
相关推荐
C#调用C++,C++调用Python并传参,包括C++向python传递图片数据,C++向python传递组数据,C++向python传递字符串数据,C++向python传递结构体数据,C++初始化python类数据并调用方法,实际案例,能直接运行,需要安装...
本项目"**C++调用python,免安装python环境运行**"提供了一种解决方案,使得C++程序能够调用Python脚本,而且不需要预先在目标系统上安装Python环境。 首先,要实现C++调用Python,通常会用到Python的`Python.h`...
本资源“C++调用Python脚本(例程)”提供了一个完整的工程实例,演示了如何在C++程序中动态地调用Python脚本,使得C++能够利用Python的灵活性和便利性。 在C++中调用Python脚本主要有两种方法:一种是通过Python的...
首先,C++调用Python主要依赖于Python的C API(Application Programming Interface),它提供了与Python解释器进行交互的接口。要实现这个功能,你需要确保已经安装了Python开发库,包括头文件和库文件,通常在Linux...
本示例探讨的是如何使用C++调用Python函数,并从Python返回数据到C++。这个过程通常涉及到Python的C API或者第三方库如`boost::python`。 首先,我们需要理解C++调用Python函数的基本流程: 1. **初始化Python解释...
首先,我们需要了解C++调用Python的基本原理。这是通过Python的动态链接库(如libpython)和Python的API接口实现的。C++程序可以加载Python解释器,执行Python脚本,传递参数,获取返回值,并处理异常。这个过程涉及...
这篇"**C++调用python demo**"提供了一个实例,演示了如何使用C++来调用Python脚本,帮助开发者理解这两种语言之间的接口操作。下面将详细阐述相关知识点。 首先,C++与Python的交互主要依赖于`Python C API`...
本示例探讨了如何使用C++调用Python函数,特别是用于发送电子邮件的场景。这种技术允许我们利用C++的高效性能和Python丰富的库资源。 首先,C++与Python之间的交互通常依赖于Python的C API(Python C Application ...
总的来说,C++调用Miniconda虚拟环境中的Python函数是一种强大且灵活的技术,它允许你在C++的高效性能和Python的丰富库之间进行无缝交互。在打包和部署时,选择合适的方法来包含Python环境是关键,这将直接影响到...
在IT领域,有时候我们需要在不同的...总结,C++调用Python脚本主要借助Qt的`QProcess`类,这使得在C++程序中利用Python的便利性变得简单。然而,选择哪种方式取决于具体项目的需求,如性能、易用性和集成复杂度等因素。
总的来说,C++调用Python3函数与类的实例代码涉及到的关键技术包括Python C API的使用、Python对象的创建、调用、错误处理以及内存管理。通过这些技术,我们可以灵活地集成Python的灵活性和C++的性能,实现跨语言的...
本文将详细探讨如何使用C++调用Python的源码,以实现二者的无缝对接。 C++调用Python主要依赖于Python的API接口——`Python C API`,这是一个供其他编程语言与Python交互的接口。首先,我们需要确保系统已经安装了...
本主题聚焦于"C++调用Python3",这是一个在Centos7操作系统上使用CLion IDE实现的实例。这样的结合使得我们可以利用C++的高性能和Python的丰富库资源。 C++是一种静态类型的、编译式的、通用的、大小写敏感的、不仅...
### C++调用Python脚本知识点详解 #### 一、背景与需求 在现代软件开发过程中,经常会出现不同编程语言间的交互需求。其中,C++作为一种高性能的语言,常常被用于核心算法或性能要求较高的模块;而Python则因其简洁...
一、配置python环境问题 1.首先安装Python(版本无所谓),安装的时候选的添加python路径到环境变量中 安装之后的文件夹如下所示: 2.在VS中配置环境和库 右击项目->属性->VC++目录 1)包含目录: Python安装路径/...
当我们需要利用Python的某些功能,但又希望程序整体运行在C++环境中时,就需要使用C++调用Python的机制。本教程将围绕“C++调用Python3.5中的函数”这一主题展开,介绍如何实现这一目标。 首先,要进行C++调用...
1. **安装Python库**:首先需要在C++环境中安装Python的开发库,这将提供必要的头文件和链接库,使得C++代码可以直接调用Python的API。 2. **初始化Python环境**:在C++程序启动时,需要调用Python的初始化函数,如...
本实例专注于"C++调用Python应用",展示了如何在C++程序中无缝集成Python脚本的功能,实现数据处理、逻辑控制等多种任务。我们将深入探讨这个主题,了解其背后的原理和实现方法。 首先,C++调用Python主要依赖于...
本文详细介绍了C++调用Python API时涉及的重要概念——全局解释器锁(GIL)和线程状态。理解这些概念对于开发高效且线程安全的跨语言程序至关重要。通过明确地管理线程状态和GIL,开发者可以在C++和Python之间建立可靠...