c++中嵌入python入门1

本人是用vc2003+python2.5学习的,其它的也应该差不了多少

0. 坏境设置
Python的include/libs目录分别加到vc的include/lib directories中去。另外,由于python没有提供debug lib,体地说,就是没有提供python25_d.lib了。你可以自己编译python的源代码来得到python25_d.lib的,偶还没试过,呵呵。而且网上找了一下也没下载到。所以,如果你想要在debug下运行程序的话,你要把pyconfig.h(在python25/include/目录下)的大概是在283行,把pragma comment(lib,"python25_d.lib")改成pragma comment(lib,"python25.lib"),让python都使用非debug lib.

1. 开始编程了
#include <python.h>
第一步就是包含python的头文件

2. 看一个很简单的例子
1)python文件test.py,很简单的定义了一个函数

#Filename test.py
def Hello():
    print "Hello, world!"

这个应该能看懂的吧?否则的话,回去再练练python吧,呵呵。《简明Python教程》Swaroop, C. H. 著。沈洁元  译。

2)cpp文件

#include <python.h> //包含头文件,在c++中嵌入python,这是必须的
int main()
{
 Py_Initialize();

PyObject * pModule = NULL;
 PyObject * pFunc   = NULL;

pModule = PyImport_ImportModule("test");
 pFunc   = PyObject_GetAttrString(pModule, "Hello");
 PyEval_CallObject(pFunc, NULL);

Py_Finalize();

return 0;
}

第一步还是包含头文件

第二步,使用python之前,要调用Py_Initialize();这个函数进行初始化。
帮助文档中如是说:
The basic initialization function is Py_Initialize(). This initializes the table of loaded modules, and creates the fundamental modules __builtin__, __main__, sys, and exceptions. It also initializes the module search path (sys.path).

反正,一开始你一定要调用。

第三步,声明一些Python的变量,PyObject类型的。其实声明也可放在前面,这个倒是无所谓的。

第四步,import module,也就是你的脚本名字,不需要加后缀名,否则会出错的。

第五步,从你import进来的module中得到你要的函数
 pFunc   = PyObject_GetAttrString(pModule, "Hello");
上面的例子已经够清楚的了,最后一个是你要得到的函数的名字

第六步,调用PyEval_CallObject来执行你的函数,第二个参数为我们要调用的函数的函数,本例子不含参数,所以设置为NULL。

第七步,调用Py_Finalize,这个根Py_Initialize相对应的。一个在最前面,一个在最后面。

第一次写教程。这个例子非常简单,本人也还在学习当中阿,只能保证大家能够把这个例子运行起来。建议大家去看python的documentaion,里面有讲怎么embedding python的。先写到这里,其实目前也只学到这么多,呵呵。下次学了更多以后再写。Over。恩。

c++中嵌入python入门2

1. 一个有一个参数的例子

python文件
#Filename test2.py

def Hello(s):
    print "Hello, world!"
    print s

cpp文件
#include <python.h>
int main()
{
 Py_Initialize();

PyObject * pModule = NULL;
 PyObject * pFunc   = NULL;
 PyObject * pArg    = NULL;

pModule = PyImport_ImportModule("test2");
 pFunc   = PyObject_GetAttrString(pModule, "Hello");
 pArg    = Py_BuildValue("(s)", "function with argument");

PyEval_CallObject(pFunc, pArg);

Py_Finalize();

return 0;
}

注意,参数要以tuple元组形式传入。因为这个函数只要一个参数,所以我们直接使用(s)构造一个元组了。

2. 一个有两个参数的例子

python文件中加入以下代码,一个加函数
def Add(a, b):
    print "a+b=", a+b

cpp文件,只改了两行,有注释的那两行
#include <python.h>
int main()
{
 Py_Initialize();

PyObject * pModule = NULL;
 PyObject * pFunc   = NULL;
 PyObject * pArg    = NULL;

pModule = PyImport_ImportModule("test2");
 pFunc   = PyObject_GetAttrString(pModule, "Add");//终于告别hello world了,开始使用新的函数
 pArg    = Py_BuildValue("(i,i)", 10, 15);//构造一个元组

PyEval_CallObject(pFunc, pArg);

Py_Finalize();

return 0;
}

其它的就类似了。。。基本上,我们知道了怎么在c++中使用python中的函数。接下来学习一下如何使用python中的

class。

附:Py_BuildValue的使用例子,来自python documentation:

Py_BuildValue("")                        None
    Py_BuildValue("i", 123)                  123
    Py_BuildValue("iii", 123, 456, 789)      (123, 456, 789)
    Py_BuildValue("s", "hello")              'hello'
    Py_BuildValue("ss", "hello", "world")    ('hello', 'world')
    Py_BuildValue("s#", "hello", 4)          'hell'
    Py_BuildValue("()")                      ()
    Py_BuildValue("(i)", 123)                (123,)
    Py_BuildValue("(ii)", 123, 456)          (123, 456)
    Py_BuildValue("(i,i)", 123, 456)         (123, 456)
    Py_BuildValue("[i,i]", 123, 456)         [123, 456]
    Py_BuildValue("{s:i,s:i}",
                  "abc", 123, "def", 456)    {'abc': 123, 'def': 456}
    Py_BuildValue("((ii)(ii)) (ii)",
                  1, 2, 3, 4, 5, 6)          (((1, 2), (3, 4)), (5, 6))

c++中嵌入python入门3

这次主要讲讲怎么把python中的class嵌入到c++中去。
顺便讲讲元组的操作和怎么编译python源代码。

1. 首先讲讲元组的操作
由于参数是通过元组传进去的,所以我们不能老是通过Py_BuildValue这个函数来操作元组,那样太不方便了。
Python提供了元组相关的操作,下面这个例子演示了如何操作。主要是下面几个函数:
//new一个元组,传入size
pArgs = PyTuple_New(argc - 3); 
//set元组的直,第一个为元组,第二个为index(从0开始),第三个为value
PyTuple_SetItem(pArgs,0,Py_BuildValue("i",2000) );
PyTuple_SetItem(pArgs,1,Py_BuildValue("i",8) );

来自python doc的一个例子

#include <Python.h>
int
main(int argc, char *argv[])
{
    PyObject *pName, *pModule, *pDict, *pFunc;
    PyObject *pArgs, *pValue;
    int i;

if (argc < 3) {
        fprintf(stderr,"Usage: call pythonfile funcname [args]/n");
        return 1;
    }

Py_Initialize();
    pName = PyString_FromString(argv[1]);
    /* Error checking of pName left out */

pModule = PyImport_Import(pName);
    Py_DECREF(pName);

if (pModule != NULL) {
        pFunc = PyObject_GetAttrString(pModule, argv[2]);
        /* pFunc is a new reference */

if (pFunc && PyCallable_Check(pFunc)) {
            pArgs = PyTuple_New(argc - 3);
            for (i = 0; i < argc - 3; ++i) {
                pValue = PyInt_FromLong(atoi(argv[i + 3]));
                if (!pValue) {
                    Py_DECREF(pArgs);
                    Py_DECREF(pModule);
                    fprintf(stderr, "Cannot convert argument/n");
                    return 1;
                }
                /* pValue reference stolen here: */
                PyTuple_SetItem(pArgs, i, pValue);
            }
            pValue = PyObject_CallObject(pFunc, pArgs);
            Py_DECREF(pArgs);
            if (pValue != NULL) {
                printf("Result of call: %ld/n", PyInt_AsLong(pValue));
                Py_DECREF(pValue);
            }
            else {
                Py_DECREF(pFunc);
                Py_DECREF(pModule);
                PyErr_Print();
                fprintf(stderr,"Call failed/n");
                return 1;
            }
        }
        else {
            if (PyErr_Occurred())
                PyErr_Print();
            fprintf(stderr, "Cannot find function /"%s/"/n", argv[2]);
        }
        Py_XDECREF(pFunc);
        Py_DECREF(pModule);
    }
    else {
        PyErr_Print();
        fprintf(stderr, "Failed to load /"%s/"/n", argv[1]);
        return 1;
    }
    Py_Finalize();
    return 0;
}

2. class操作
把下面加入到test2.py中去。定义了一个很简单的类,有一个name成员变量,一个printName成员函数
class TestClass:
    def __init__(self,name):
        self.name = name

def printName(self):
        print self.name

cpp文件
#include <python.h>
int main()
{
 Py_Initialize();

PyObject * pModule = NULL;
 PyObject * pFunc   = NULL;
 PyObject * pArg    = NULL;
 PyObject * pClass  = NULL;
 PyObject * pObject = NULL;

pModule = PyImport_ImportModule("test2");
 pClass  = PyObject_GetAttrString(pModule, "TestClass");//得到那个类
 pArg = PyTuple_New(1);
 PyTuple_SetItem(pArg, 0, Py_BuildValue("s", "Jacky"));
 pObject = PyEval_CallObject(pClass, pArg);//生成一个对象,或者叫作实例

pFunc = PyObject_GetAttrString(pObject, "printName");//得到该实例的成员函数
 PyEval_CallObject(pFunc, NULL);//执行该实例的成员函数

Py_Finalize();

return 0;
}

没有什么资料,就先写到这里了。下面介绍一下怎么build python25的源代码

3. 编译python源代码
为什么要编译呢?因为没有python25_d.lib!呵呵。顺便可以了解一下代码结构。
解压缩后,有好多目录,其中pcbuild和pcbuild8是我们要的。pcbuild对应着vc7.1的,pcbuild8对应着vc8.0的
因为在用vc7.1,也就是2003了。所以我就说说怎么用2003来编译吧。事实上是从一位牛人那里学来的

http://blog.donews.com/lemur/archive/2005/12/17/660973.aspx,那位大哥大概一年半前就在解剖python了,厉害

阿。看来我只能后来居上了,娃哈哈。我按照他说的试了一下,编译成功!

不过遇到一点小问题,用vc2003打开那个solution的时候,发现作者没有把source code control去掉,郁闷!害的我

们打开的时候一堆messagebox。不过不用管它就好了,一直确定。最后试了一下那个python25_d.lib,没问题。不过记

得把python25_d.dll copy到一个能被找到的目录,比如说c:/windows/system32/下面。python25.dll也在这个目录下

面。over。恩。

c++中嵌入python入门4 之 Boost.Python

坏境python25 + vs2005 (2005真耗资源阿。。。)

有一段时间没写blog了。这几天都在研究怎么封装c++,让python可以用c++的库。在网上发现了boost.python这个好咚咚。不

过在使用过程中碰到一点问题。本文教大家如何把

char const* greet()
{
   return "hello, world";
}

封装成python。实际上这是python教程里面的咚咚。

首先下载Boost,www.boost.org。boost.python在boost里面了。在visual studio 2005 command prompt中navigation到

boost/boost_1_34_0/下。记得一定要用visual studio 2005 command prompt这个vs2005带的tools,不要用cmd.exe,否则会

碰到很多错误的。然后就是把bjam.exe拷贝到一个能被找到的目录下,或者直接也拷贝到boost/boost_1_34_0/下即可。然后,

设置python的根目录和python的版本,也可直接把它们加到坏境目录中,那样就不用每次都设置一下。
set PYTHON_ROOT=c:/python25
set PYTHON_VERSION=2.5

接着就可以直接运行了,bjam -sTOOLS=vc-8_0
整个编译过程要很长时间。。。

成功之后,就会有好多个boost_python-vc80-****.dll,.lib的,把他们都拷贝到一个能被系统找到的目录,不妨直接把他们都

扔到c:/windows/system32下。

接着,我们开始编译hello。navigation到boost/boost_1_34_0/libs/python/example/tutorial下,bjam -sTOOLS=vc-8_0运行

,在bin的目录下即会生成hello.pyd。这下就基本成功了,如果没成功的话,check一下上面boost_python的那些dll能否被系

统找到。另外,这里有python25的一个bug。。。我花了很长时间才在python的mail lists中找到了。寒。。。

错误如下所示:
D:/Learn/Python/boost/boost_1_34_0/libs/python/example/tutorial>bjam
Jamroot:17: in modules.load
rule python-extension unknown in module Jamfile</D:/Learn/Python/boost/boost_1_3
4_0/libs/python/example/tutorial>.
D:/Learn/Python/boost/boost_1_34_0/tools/build/v2/build/project.jam:312: in load
-jamfile
D:/Learn/Python/boost/boost_1_34_0/tools/build/v2/build/project.jam:68: in load
D:/Learn/Python/boost/boost_1_34_0/tools/build/v2/build/project.jam:170: in proj
ect.find
D:/Learn/Python/boost/boost_1_34_0/tools/build/v2/build-system.jam:237: in load
D:/Learn/Python/boost/boost_1_34_0/libs/python/example/../../../tools/build/v2/k
ernel/modules.jam:261: in import
D:/Learn/Python/boost/boost_1_34_0/libs/python/example/../../../tools/build/v2/k
ernel/bootstrap.jam:132: in boost-build
D:/Learn/Python/boost/boost_1_34_0/libs/python/example/boost-build.jam:7: in mod
ule scope

解决办法如下:
在boost/boost_1_34_0/tools/build/v2/目录下找到user-config.jam文件,打开在
import toolset : using ;
下面加一行代码:
using python ;
再重新编译一下boost,然后就没问题了。tutorial里面的hello能顺利编译通过。ps.这个问题困扰了我好长时间。。sigh。。

编译成功后会产生一个hello.pyd,在bin的目录下面。

有好多办法测试此hello.pyd是否可以用。
方法一,把它拷贝到python25/dlls下,打开IDLE,
>>> import hello
>>> hello.greet()
'hello, world'
>>> 
方法二,直接在当前目录下写一个python文件,然后直接调用hello.pyd即可。总之,hello.pyd就是一个python文件了。。嗯

。操作hello.pyd根其他python文件是一样的。
这样就成功了。

如果碰到如下错误,是因为系统找不到boost_python的dll。强烈建议把他们都扔到system32下!。

>>> import hello

Traceback (most recent call last):
  File "<pyshell#0>", line 1, in <module>
    import hello
ImportError: DLL load failed: 找不到指定的模块。
>>>

说明,hello.cpp在boost/boost_1_34_0/libs/python/example/tutorial目录下。里面的内容是:

//  Copyright Joel de Guzman 2002-2004. Distributed under the Boost
//  Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt 
//  or copy at http://www.boost.org/LICENSE_1_0.txt)
//  Hello World Example from the tutorial
//  [Joel de Guzman 10/9/2002]

char const* greet()
{
   return "hello, world";
}

#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
using namespace boost::python;

BOOST_PYTHON_MODULE(hello)
{
    def("greet", greet);
}

其中
BOOST_PYTHON_MODULE(hello)
{
    def("greet", greet);
}
是对greet从c++向python的一个封装声明吧,装换就交给boost了。

先写到这里了。下次再写。。嗯

python与c++交互学习入门之5

这次讲讲,如何扩展c++库。通过boost.python把c++库编译成python能够调用的dll。

通过上一次的教程后,大家都应该会使用boost.python了。把c++程序编译成pyd文件。由于c++有很多特性,所以,如果你的程

序用了很多的c++特性的话,那么你必须做很多工作了。像虚拟函数,函数重载,继承,默认值等等。具体如何转化,请参

boost.python的文档了。

这几天尝试着把c++程序库编译成python可调用的dll,不知道为什么一直不可用。。很是郁闷。老是显示如下的错误:

Traceback (most recent call last):
  File "<pyshell#3>", line 1, in <module>
    import pydll
ImportError: No module named pydll

意思是说找不到dll。我把dll都copy到python/dlls下了还是不行,而且我确定python的sys.path包含了python/dlls目录了。

很是不解。网上也很难找到资料,google了很长时间找不到有用的资料,好像中文方面的资料很少的。今天尝试了一下google

英文资料,终于有了新的发现:
http://mail.python.org/pipermail/c++-sig/2007-February/011971.html
You are using Python2.5. In this version of Python you have to have
file extension
to be "pyd" - sge.pyd

-- 
Roman Yakovenko
C++ Python language binding
http://www.language-binding.net/

有人碰到的问题跟我的是一样的。后面那个Roman回答了一下,是文件扩展名的问题!!!为什么不支持dll呢?不解。回去试

了一下把后缀名改了就成功了。。。why???

下面来看一下我的那个简单的例子:
这个例子来自于网上,
http://www.vckbase.com/document/viewdoc/?id=1540
C++ 扩展和嵌入 Python
作者:胡金山
源码下载地址:http://www.vckbase.com/code/downcode.asp?id=2777

这是一个非常简单的dll工程。给python提供了一个函数static PyObject* Recognise(PyObject *self, PyObject *args)。

1、不使用boost.python库来直接构建dll
接下来,我们来用C++为Python编写扩展模块(动态链接库),并在Python程序中调用C++开发的扩展功能函数。生成一个取名为

pyUtil的Win32 DLL工程,除了pyUtil.cpp文件以外,从工程中移除所有其它文件,并填入如下的代码:

// pyUtil.cpp
#ifdef PYUTIL_EXPORTS
#define PYUTIL_API __declspec(dllexport)
#else
#define PYUTIL_API __declspec(dllimport)
#endif

#include<windows.h>
#include<string>
#include<Python.h>
BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
        )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}
std::string Recognise_Img(const std::string url)
{
    //返回结果
    return "从dll中返回的数据... : " +url;
}
static PyObject* Recognise(PyObject *self, PyObject *args)
{
    const char *url;
    std::string sts;
    if (!PyArg_ParseTuple(args, "s", &url))
        return NULL;
    sts = Recognise_Img(url);
    return Py_BuildValue("s", sts.c_str() );
}
static PyMethodDef AllMyMethods[] = {
    {"Recognise",  Recognise, METH_VARARGS},//暴露给Python的函数
    {NULL,      NULL}        /* Sentinel */
};
extern "C" PYUTIL_API void initpyUtil()
{
    PyObject *m, *d;
    m = Py_InitModule("pyUtil", AllMyMethods); //初始化本模块,并暴露函数
    d = PyModule_GetDict(m);
}

在Python代码中调用这个动态链接库: (记得把dll的扩展名改为.pyd,另外dll的路径要能够被检索到)
import pyUtil
result = pyUtil.Recognise("input url of specific data")
print "the result is: "+ result

2、使用boost.python库来构建dll
用C++为Python写扩展时,如果您愿意使用Boost.Python库的话,开发过程会变得更开心J,要编写一个与上述pyUtil同样功能

的动态链接库,只需把文件内容替换为下面的代码。当然,编译需要boost_python.lib支持,运行需要boost_python.dll支持

。 
#include<string>
#include <boost/python.hpp>
using namespace boost::python;
#pragma comment(lib, "boost_python.lib")
std::string strtmp;
char const* Recognise(const char* url)
{
    strtmp ="从dll中返回的数据... : ";
    strtmp+=url;
    return strtmp.c_str();
}
BOOST_PYTHON_MODULE(pyUtil)
{
    def("Recognise", Recognise);
}

可以非常明显地看到,用了boost.python库之后,简单了很多。因为boost.python为你做了很多的事情。。恩。

很好的c++和Python混合编程文章的更多相关文章

  1. 在Qt(C++)中与Python混合编程

    一.PythonQt库 在Qt(C++)中与Python混合编程,可以使用PythonQt库. 网站首页:http://pythonqt.sourceforge.net 下载页面:https://so ...

  2. 【目录】Matlab和C#混合编程文章目录

    本博客所有文章分类的总目录链接:[总目录]本博客博文总目录-实时更新 1.Matlab和C#混合编程文章目录 9.接触Matlab10年后的一个总结,随时使用Matlab要掌握的一些要点 8.国内第一 ...

  3. C++/Python 混合编程 Clion IDE 搭建

    1.Clion IDE 环境 2.TdmGcc C++ 编译器 3.WinPython Python 科学计算环境 4.MySQL SQL 数据库 5.Git GitHub 版本控制 插件

  4. C语言调用Python 混合编程

    导语 Python有很多库,Qt用来编写界面,自然产生C++调用Python的需求.一路摸索,充满艰辛 添加头文件搜索路径,导入静态库 我的python头文件搜索路径:C:\Python27amd64 ...

  5. C++和Python混合编程

    为何人工智能(AI)首选Python?读完这篇文章你就知道了:https://blog.csdn.net/qq_41769259/article/details/79419322 C++调用Pytho ...

  6. 国内第一部C#.Net调用Matlab混合编程视频教程

       本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新 Matlab和C#混合编程文章目录:[目录]Matlab和C#混合编程文章目录 一.视频说明 2014年的5.1,我将这套视频教 ...

  7. 【5.1送礼】国内第一部Matlab和C#.Net混合编程视频教程【免费】

                  本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新    Matlab和C#混合编程文章目录 :[目录]Matlab和C#混合编程文章目录 上一次写博客很久了 ...

  8. 【原创】Matlab.NET混合编程技巧之找出Matlab内置函数

                  本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新    Matlab和C#混合编程文章目录 :[目录]Matlab和C#混合编程文章目录 Matlab与.N ...

  9. 【原创】Matlab.NET混合编程技巧之直接调用Matlab内置函数

                  本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新    Matlab和C#混合编程文章目录 :[目录]Matlab和C#混合编程文章目录 在我的上一篇文章[ ...

随机推荐

  1. ZT-----用javascrip写一个区块链

    几乎每个人都听说过像比特币和以太币这样的加密货币,但是只有极少数人懂得隐藏在它们背后的技术.在这篇博客中,我将会用JavaScript来创建一个简单的区块链来演示它们的内部究竟是如何工作的.我将会称之 ...

  2. 【Python进阶】用 Python 统计字数

    问题描述: 用 Python 实现函数 count_words(),该函数输入字符串 s 和数字 n,返回 s 中 n 个出现频率最高的单词.返回值是一个元组列表,包含出现次数最高的 n 个单词及其次 ...

  3. 自然语言处理 - 如何通俗地理解TFIDF?

    本博客属个人学习笔记,如有疏漏,欢迎在评论留言指出~转载请注明. 在自然语言处理中,TFIDF常常被人提及.很多材料都提及TFIDF中的“普遍重要性”,但很少有材料去简单解释其中的原理.TFIDF其实 ...

  4. 17 Tips For Writing An Excellent Email Subject Line

    Out of the billions of emails that are sent every day, how can you make sure that yours stands out? ...

  5. 每天一个linux命令集

    linux命令汇总,装载来自: http://www.cnblogs.com/peida/category/309012.html

  6. postion一句话很管用

    relative和absolute有本质区别,relative是相对与postion为默认值的时候元素自身位置来定位:而absolute是相对最近position为relative或absolute的 ...

  7. Spring学习(五)——Spring注解(一)

    ---恢复内容开始--- 概述 注释配置相对于 XML 配置具有很多的优势: 它可以充分利用 Java 的反射机制获取类结构信息,这些信息可以有效减少配置的工作.如使用 JPA 注释配置 ORM 映射 ...

  8. lintcode-427-生成括号

    427-生成括号 给定 n 对括号,请写一个函数以将其生成新的括号组合,并返回所有组合结果. 样例 给定 n = 3, 可生成的组合如下: "((()))", "(()( ...

  9. C#高级编程 (第六版) 学习 第五章:数组

    第五章 数组 1,简单数组 声明:int[] myArray; 初始化:myArray = new int[4]; 为数组分配内存. 还可以用如下的方法: int[] myArray = new in ...

  10. UserAgent 设置 php 抓取网页

    转载:http://www.webkaka.com/tutorial/php/2013/111846/ hp抓取网页,可谓轻而易举,几行代码就可以搞定.不过,如果你有所疏忽,程序写得不够严密,就会出现 ...