• vc++调用pytho,可带返回值,供大家学习测试
  • C++调用python

    2017-05-13 11:42:41
    C++调用python C++中调用Python脚本的意义就不讲了,至少你可以把它当成文本形式的动态链接库,需要的时候还可以改一改,只要不改变接口, C++的程序一旦编译好了,再改就没那么方便了。 皮皮blog VS中编译运行 ...

    http://blog.csdn.net/pipisorry/article/details/49532341

    C++调用python

    在C/C++中嵌入Python,可以使用Python提供的强大功能,通过嵌入Python可以替代动态链接库形式的接口,这样可以方便地根据需要修改脚本代码,而不用重新编译链接二进制的动态链接库。至少你可以把它当成文本形式的动态链接库,需要的时候还可以改一改,只要不改变接口, C++的程序一旦编译好了,再改就没那么方便了。

    C++调用Python有两种方式

    第一种方式:通过找到Python模块,类,方法,构造参数来调用。

    第二中方式,就是通过构造出一个Python的脚本,用python引擎来执行。

    第一种方式可能更为优雅,符合大多数的反射调用的特点。(如c#的反射机制,c#调用Com+,c#调用javascript脚本等)。
    一个问题:两种语言互相调用的时候,需要做数据结构(如基本类型,字符串,整数类型等,以及自定义的类等类型)间的转换,共享内存中的一个对象。比如,如何将C++的对象实例传入python中,并在python中使用。c++和python并不在一个进程中,因此可以使用boost的shared_ptr来实现。Python调用C++,换句话说就是需要把C++封装成Python可以“理解”的类型。同理可知C++怎么去调用Python脚本。
    下面这个例子,主要是演示了c++调用python,可以在c++中形成一个python脚本,然后利用PyRun_SimpleString调用;并且,构造一个c++的对象,传入到python中,并在python的脚本中调用其函数。

    皮皮blog


    VS中编译运行

    vs安装配置

    安装python3.4,然后配置系统环境变量。

    安装Visual Studio2010(注意可以不用安装其它好多东西,只要安装c++就可以了)。[Visual Studio相关设置]

    vs中新建一个win32控制台应用程序,一路确定完成。

    VS2010的配置(设置编译环境)

    1. c++调用python需要在vs2010中的cpp文件中加入<Python.h>,这个头文件在python安装目录Python\include下

    要成功引入就要把Python.h的头文件目录(如D:\python3.4.2\include放在菜单 > 项目 > 属性 > C/C++ > 常规 > 附加包含目录下(或者右键项目)

    2. 还需要一个python34.lib,如果不导入的话,会提示你出现这个文件的缺失。文件在python\libs下,找到此文件之后进入VS2010,菜单 >项目 > 属性 > 配置属性 > VC++目录 > 库目录,把刚才的绝对路径(如D:\python3.4.2\libs)添加进去,此时变成这样的了:D:\python3.4.2\libs;$(VCInstallDir)lib;$(VCInstallDir)atlmfc\lib;$(WindowsSdkDir)lib;$(FrameworkSDKDir)\lib。这样就可以在VC程序中执行python文件了。

    或者把D:\python3.4.2\libs放进项目 > 属性 > 配置属性 > 链接器 > 常规 > 附加库目录中。

    Note: 上面的设置是对某个模式生效,如果将运行模式从debug改成了release,要再进去设置,否则设置不成功。

    程序编辑

    编辑c++代码

    将PythonInvoke.cpp文件改成下面的代码,用于调用python程序helloworld

    // PythonInvoke.cpp : 定义控制台应用程序的入口点。
    #include "stdafx.h"
    #include<Python.h>

    void main(){
        Py_Initialize(); /*初始化python解释器,告诉编译器要用的python编译器*/
        PyRun_SimpleString("import helloworld"); /*调用python文件*/
        PyRun_SimpleString("helloworld.printHello()");/*调用python文件中的函数*/
        Py_Finalize(); /*结束python解释器,释放资源*/
        system("pause");
    }

    Note: 当python代码有错误时,PyImport_ImportModule函数返回NULL;

    另一种调用方式的代码

    #include<Python.h>//前面所做的一切配置都是为了调用这个头文件和相关库
    #include<iostream>
    using namespace std;
    int main(){
    Py_Initialize();//使用python之前,要调用Py_Initialize();这个函数进行初始化
    PyObject * pModule = NULL;//声明变量
    PyObject * pFunc = NULL;// 声明变量
    pModule =PyImport_ImportModule("helloworld");//这里是要调用的文件名
    pFunc= PyObject_GetAttrString(pModule, "Hello");//这里是要调用的函数名
    PyEval_CallObject(pFunc, NULL);//调用函数
    Py_Finalize();//调用Py_Finalize,这个根Py_Initialize相对应的。
    return 0;
    }

    编辑python代码

    在项目源文件中,添加文件命令为helloworld.py

    def printHello():
        print("Hello World!")

    .py文件保存在.cpp同目录下

    Note: 不能将python文件的名字命名为test.py,否则报错,由于test.py是python内置python脚本文件,也就是python有自己的test.py文件,并且其优先级比你的高。。

    皮皮blog

    程序运行

    如果你安装的python是64位的,则vs2010中需要把解决方案平台定位‘X64’的模式下,否则配置不成功。

    报错:fatal error LNK1112: 模块计算机类型“X86”与目标计算机类型“x64”冲突。[fatal error LNK1112]

    Release模式下运行

    release模式下运行不用设置太多东西

    修改运行选项

    Debug改为Release

    win32下拉配置,新建x64,一路确定


    注意,执行下面之前要在release模式下再设置一次VS2010的配置

    运行

    运行成功!

    Debug模式下运行

    1. Debug下,python/libs目录下的python34.lib需要复制并重命名为python34_d.lib的形式

    设置:项目 > 属性 > 配置属性 > 链接器 > 输入 > 附加依赖库 > python34_d.lib

    [源码编译 python 生成 python26_d.lib ; 处理 error c101008d]

    为什么会有python34.lib和python34_d.lib的差别就是因为:python_d.lib是 库的调试后形式,当我们以debug模式编译工程时,python就用这个lib文件,但是这个文件是不可用 的。对于这点,最快的办法就是强制要求python在任何情况下都是用非调试版本,就可以了。

    就是说,不重命名的解决方法,对python头文件python/include/pyconfig.h进行修改:

    #           if defined(_DEBUG)
    #               pragma  comment(lib,"python34_d.lib")
    #           elif defined(Py_LIMITED_API)
    #               pragma comment(lib,"python3.lib")
    #           else
    #               pragma comment(lib,"python34.lib")
    #           endif /* _DEBUG */
    

    将DEBUG条件下的lib由python34_d.lib改为python34.lib.

    #           if defined(_DEBUG)
    #               pragma  comment(lib,"python34.lib")
    

    2. 64位debug下的方案解决
    右键项目名,点击属性,弹出项目属性页,找到链接器—高级,修改右侧的目标计算机,选择有X64的那个选项。如果没有,则选择编译器Configuration Manager中new,添加amd64等平台,然后工程属性中选择x64。

    这一步好像也不用,只要在运行时选择x64就可以了。见3.运行。

    Note: 属性 - 链接器 - 命令行 -附加选项:如果里面有"/MACHINE:I386"之类的,要删了。

    3. 32位库改成64位库

    项目 > 属性 > 配置属性 > Vc++目录> 库目录,这里要将32位库改成64位库,相当重要!

    $(VCInstallDir)lib\amd64
    $(VCInstallDir)atlmfc\lib\amd64
    $(WindowsSdkDir)lib\x64
    如:将D:\python3.4.2\libs;$(VCInstallDir)lib;$(VCInstallDir)atlmfc\lib;$(WindowsSdkDir)lib;$(FrameworkSDKDir)\lib
    换成D:\python3.4.2\libs;$(VCInstallDir)lib\amd64;$(VCInstallDir)atlmfc\lib\amd64;$(WindowsSdkDir)lib\x64;$(FrameworkSDKDir)\lib

    没有这样设置会报错:msvcprtd.lib(MSVCP100D.dll) : fatal error LNK1112: module machine type ‘X86’ conflicts with target machine type ‘x64’

    msvcprtd.lib(MSVCP100D.dll) : fatal error LNK1112: 模块计算机类型“X86”与目标计算机类型“x64”冲突

    [msvcprtd.lib(MSVCP100D.dll) : fatal error LNK1112: module machine type ‘X86’ conflicts with target machine type ‘x64’]

    [msvcprtd.lib(MSVCP100D.dll) : fatal error LNK1112: module machine type 'X86' conflicts with target machine type 'x64']

    还有一个cmake类似的问题[fatal error LNK1112: 模块计算机类型“X86”与目标计算机类型“x64”冲突——我的解决方案]

    3. 运行:右键项目名,选择清理解决方案,清理完成之后重新生成解决方案,然后选择X64平台编译器去debug,便可以调试成功。

    可能存在的错误

    c++调用python时报错LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏

    这个是由于日志文件引起的,可以将项目\属性\配置属性\清单工具\输入和输出\嵌入清单:原来是“是”,改成“否”。
    或者将项目\属性\配置属性\链接器\清单文件\生成清单:原来是“是”,改成“否”。
    如果仍然无效,判断是否已经安装了VS2012,如果已经安装,需要安装VS2010 sp1补丁。

    [链接器工具错误 LNK1123]

    但是如果程序要加写rc,必须带清单才能正常使用。所以这种治标不治本的方法失效了。

    还有一种解决方案:

    出现这个问题的原因:可能是因为系统最近多次更新,出现了两个版本的cvtres.exe。而系统变量里将这俩都引用了,编译的时候,不知道用哪个了,导致出错。所以要删掉一个。

    一个在C:\Windows\Microsoft.NET\Framework\v4.0.30319\cvtres.exe,另一个在你安装VS的软件目录..\Microsoft Visual Studio 10.0\vc\bin\cvtres.exe

    然后右键属性-->详细信息 查看两者版本号,把老的Kill掉,就完了。

    [彻底解决 LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏]

    编译时_RTC_Shutdown和_RTC_InitBase相关错误的解决方法:

    error LNK2001: 无法解析的外部符号 _RTC_Shutdown;error LNK2001: 无法解析的外部符号 _RTC_InitBase

    右键点击项目,修改:属性 > 配置属性 > C/C++ > 代码生成 > 基本运行时检查,将值从“两者(......)”改为“默认值”。

    [编译时_RTC_Shutdown和_RTC_InitBase相关错误的解决方法]
    LINK : error LNK2001: 无法解析的外部符号 mainCRTStartup

    其它错误

    error LNK2019: 无法解析的外部符号 __imp_system,该符号在函数 main 中被引用

    原因是system("pause");没有include

    [C++调用python配置及编译出现的问题]

    皮皮blog


    命令行中直接调用执行

    编译选项, 需要手动指定Python 的include 路径, 和链接接路径。

    代码:
    g++ Python.cpp -o Python-I/usr/include/python2.5 -L/usr/lib/python2.5-lpython2.5

    皮皮blog



    C++调用python带参数传递

    调用Python函数时,参数的传递,就是c++的类型,怎么转换成Python的类型;另外一个问题是,Python函数的返回值,怎么转换成C++中的类型。

    在C程序中用Python脚本传递参数,或者获得Python脚本的返回值,则要使用更多的函数来编写C程序。由于Python有自己的数据类型,因此在C程序中要使用专门的API对相应的数据类型进行操作。

    常用的函数有以下几种

    1.数字与字符串处理

    在Python/C API中提供了Py_BuildValue()函数对数字和字符串进行转换处理,使之变成Python中相应的数据类型。其函数原型如下所示。

    PyObject* Py_BuildValue( const char *format, ...)

    其参数含义如下。

    ·     format:格式化字符串,如表8-1所示。

    Py_BuildValue()函数中剩余的参数即要转换的C语言中的整型、浮点型或者字符串等。其返回值为PyObject型的指针。在C语言中,所有的Python类型都被声明为PyObject型。

     

    2.列表操作

    在Python/C API中提供了PyList_New()函数用以创建一个新的Python列表。PyList_New()函数的返回值为所创建的列表。其函数原型如下所示。

    PyObject* PyList_New( Py_ssize_t len)

    其参数含义如下。

    ·     len:所创建列表的长度。

    当列表创建以后,可以使用PyList_SetItem()函数向列表中添加项。其函数原型如下所示。

    int PyList_SetItem( PyObject *list, Py_ssize_t index, PyObject *item)

    其参数含义如下。

    ·     list:要添加项的列表。

    ·     index:所添加项的位置索引。

    ·     item:所添加项的值。

    同样可以使用Python/C API中PyList_GetItem()函数来获取列表中某项的值。PyList_GetItem()函数返回项的值。其函数原型如下所示。

    PyObject* PyList_GetItem( PyObject *list, Py_ssize_t index)

    其参数含义如下。

    ·     list:要进行操作的列表。

    ·     index:项的位置索引。

    Python/C API中提供了与Python中列表操作相对应的函数。例如列表的append方法对应于PyList_Append()函数。列表的sort方法对应于PyList_Sort()函数。列表的reverse方法对应于PyList_Reverse()函数。其函数原型分别如下所示。

    int PyList_Append( PyObject *list, PyObject *item)

    int PyList_Sort( PyObject *list)

    int PyList_Reverse( PyObject *list)

    对于PyList_Append()函数,其参数含义如下。

    ·     list:要进行操作的列表。

    ·     item:要参加的项。

    对于PyList_Sort()和PyList_Reverse()函数,其参数含义相同。

    ·     list:要进行操作的列表。

     

    3.元组操作

    在Python/C API中提供了PyTuple_New()函数,用以创建一个新的Python元组。PyTuple_New()函数返回所创建的元组。其函数原型如下所示。

    PyObject* PyTuple_New( Py_ssize_t len)

    其参数含义如下。

    ·     len:所创建元组的长度。

    当元组创建以后,可以使用PyTuple_SetItem()函数向元组中添加项。其函数原型如下所示。

    int PyTuple_SetItem( PyObject *p, Py_ssize_t pos, PyObject *o)

    其参数含义如下所示。

    ·     p:所进行操作的元组。

    ·     pos:所添加项的位置索引。

    ·     o:所添加的项值。

    可以使用Python/C API中PyTuple_GetItem()函数来获取元组中某项的值。PyTuple_GetItem()函数返回项的值。其函数原型如下所示。

    PyObject* PyTuple_GetItem( PyObject *p, Py_ssize_t pos)

    其参数含义如下。

    ·     p:要进行操作的元组。

    ·     pos:项的位置索引。

    当元组创建以后可以使用_PyTuple_Resize()函数重新调整元组的大小。其函数原型如下所示。

    int _PyTuple_Resize( PyObject **p, Py_ssize_t newsize)

    其参数含义如下。

    ·     p:指向要进行操作的元组的指针。

    ·     newsize:新元组的大小。

     

    4.字典操作

    在Python/C API中提供了PyDict_New()函数用以创建一个新的字典。PyDict_New()函数返回所创建的字典。其函数原型如下所示。

    PyObject* PyDict_New()

    当字典创建后,可以使用PyDict_SetItem()函数和PyDict_SetItemString()函数向字典中添加项。其函数原型分别如下所示。

    int PyDict_SetItem( PyObject *p, PyObject *key, PyObject *val)

    int PyDict_SetItemString( PyObject *p, const char *key, PyObject *val)

    其参数含义如下。

    ·     p:要进行操作的字典。

    ·     key:添加项的关键字,对于PyDict_SetItem()函数其为PyObject型,对于PyDict_SetItemString()函数其为char型。

    ·     val:添加项的值。

    使用Python/C API中的PyDict_GetItem()函数和PyDict_GetItemString()函数来获取字典中某项的值。它们都返回项的值。其函数原型分别如下所示。

    PyObject* PyDict_GetItem( PyObject *p, PyObject *key)

    PyObject* PyDict_GetItemString( PyObject *p, const char *key)

    其参数含义如下。

    ·     p:要进行操作的字典。

    ·     key:添加项的关键字,对于PyDict_GetItem()函数其为PyObject型,对于PyDict_GetItemString()函数其为char型。

    使用Python/C API中的PyDict_DelItem()函数和PyDict_DelItemString()函数可以删除字典中的某一项。其函数原型如下所示。

    int PyDict_DelItem( PyObject *p, PyObject *key)

    int PyDict_DelItemString( PyObject *p, char *key)

    其参数含义如下。

    ·     p:要进行操作的字典。

    ·     key:添加项的关键字,对于PyDict_DelItem()函数其为PyObject型,对于PyDict_DelItemString()函数其为char型。

    使用Python/C API中的PyDict_Next()函数可以对字典进行遍历。其函数原型如下所示。

    int PyDict_Next( PyObject *p, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue)

    其参数含义如下。

    ·     p:要进行遍历的字典。

    ·     ppos:字典中项的位置,应该被初始化为0。

    ·     pkey:返回字典的关键字。

    ·     pvalue:返回字典的值。

    在Python/C API中提供了与Python中字典操作相对应的函数。例如字典的item方法对应于PyDict_Items()函数。字典的keys方法对应于PyDict_Keys()函数。字典的values方法对应于PyDict_Values()函数。其函数原型分别如下所示。

    PyObject* PyDict_Items( PyObject *p)

    PyObject* PyDict_Keys( PyObject *p)

    PyObject* PyDict_Values( PyObject *p)

    其参数含义如下。

    ·     p:要进行操作的字典。

     

    5.释放资源

    Python使用引用计数机制对内存进行管理,实现自动垃圾回收。在C/C++中使用Python对象时,应正确地处理引用计数,否则容易导致内存泄漏。在Python/C API中提供了Py_CLEAR()、Py_DECREF()等宏来对引用计数进行操作。

    当使用Python/C API中的函数创建列表、元组、字典等后,就在内存中生成了这些对象的引用计数。在对其完成操作后应该使用Py_CLEAR()、Py_DECREF()等宏来销毁这些对象。其原型分别如下所示。

    void Py_CLEAR( PyObject *o)

    void Py_DECREF( PyObject *o)

    其参数含义如下。

    ·     o:要进行操作的对象。

    对于Py_CLEAR()其参数可以为NULL指针,此时,Py_CLEAR()不进行任何操作。而对于Py_DECREF()其参数不能为NULL指针,否则将导致错误。

     

    6.模块与函数

    使用Python/C API中的PyImport_Import()函数可以在C程序中导入Python模块。PyImport_Import()函数返回一个模块对象。其函数原型如下所示。

    PyObject* PyImport_Import( PyObject *name)

    其参数含义如下。

    ·     name:要导入的模块名。

    使用Python/C API中的PyObject_CallObject()函数和PyObject_CallFunction()函数,可以在C程序中调用Python中的函数。其参数原型分别如下所示。

    PyObject* PyObject_CallObject( PyObject *callable_object, PyObject *args)

    PyObject* PyObject_CallFunction( PyObject *callable, char *format, ...)

    对于PyObject_CallObject()函数,其参数含义如下。

    ·     callable_object:要调用的函数对象。

    ·     args:元组形式的参数列表。

    对于PyObject_CallFunction()函数,其参数含义如下。

    ·     callable_object:要调用的函数对象。

    ·     format:指定参数的类型。

    ·     ...:向函数传递的参数。

    使用Python/C API中的PyModule_GetDict()函数可以获得Python模块中的函数列表。PyModule_GetDict()函数返回一个字典。字典中的关键字为函数名,值为函数的调用地址。其函数原型如下所示。

    PyObject* PyModule_GetDict( PyObject *module)

    其参数含义如下。

    ·     module:已导入的模块对象。

    8.2.3 在C中嵌入Python实例

    在VC++ 6.0中新建一个名为“EmbPython”的空“Win32 Console Application”工程。向其添加如下所示的“EmbPython.c”文件。

     

    程序输出如下所示。

    -==在C中嵌入Python==-

    使用Python中的sum函数求解下列数之和

    0       1       2       3       4

    Using Function sum

    The result is: 10

    使用Python中的函数分割以下字符串:

    this is an example

    结果如下所示:

    this

    is

    an

    example

    按回车键退出程序

    [Python嵌入C/C++ (Python核心编程)]

    C++转换成Python类型,Py_BuildValue()

    http://www.python.org/doc/1.5.2p2/ext/buildValue.html

    1. PyObject* pArgs=PyTuple_New(1); //有几个参数,就是几
    2. PyTuple_SetItem(pArgs,0,Py_BuildValue("i",3));  //初始第一个参数,数据类型是i,就是int,值是3
    返回值转换如,PyArg_ParseTuple[PyArg_ParseTuple]

    皮皮blog


    python调用c++问题

    “如果没有参数从python到C++, 是正常的,但是有参数就废了报错”。我尝试实现并找到答案。
    http://stackoverflow.com/questions/145270/calling-c-c-from-python
    1. 无参数 函数声明C可用函数
    2. 有参数 那么实用SWIG  也就是我们需要一个接口文件 即

    z.i file
    %{
    #include "z.h"
    extern 函数名(参数1, 参数2,...);
    %}
    SWIG在不同语言互相调用发挥很重要的作用。


    相关话题

    SWIG
    有一个外部工具叫SWIG,是Simplified Wrapper and Interface Generator 的缩写。其作者为David Beazley,同时也是Python Essential Referenc 一书的作者。这个工具可以根据特别注释过的C/C++头文件生成能给Python,Tcl 和Perl 使用的包装代码。使用SWIG 可以省去你写前面所说的样板代码的时间。你只要关心怎么用C/C++解决你的实际问题就好了。你所要做的就是按SWIG 的格式编写文件,其余的就都由SWIG 来完成。你可以通过下面的网址找到关于SWIG 的更多信息。
    http://swig.org
    Pyrex
    创建C/C++扩展的一个很明显的坏处是你必须要写C/C++代码。你能利用它们的优点,但更重要的是,你也会碰到它们的缺点。Pyrex 可以让你只取扩展的优点,而完全没有后顾之忧。它是一种更偏向Python 的C 语言和Python 语言的混合语言。事实上,Pyrex 的官方网站上就说“Pyrex 是具有C 数据类型的Python“。你只要用Pyrex 的语法写代码,然后运行Pyrex 编译器去编译源代码。Pyrex会生成相应的C 代码,这些代码可以被编译成普通的扩展。你可以在它的官方网站下载到Pyrex:
    http://cosc.canterbury.ac.nz/~greg/python/Pyrex
    Psyco
    Pyrex 免去了我们再去写纯C 代码的麻烦。不过,你要去学会它的那一套与众不同的语法。最后,你的Pyrex 代码还是会被转成C 的代码。无论你用C/C++,C/C++加上SWIG,还是Pyrex,都是因为你想要加快你的程序的速度。如果你可以在不改动你的Python 代码的同时,又能获得速度的提升,那该多好啊。
    Psyco 的理念与其它的方法截然不同。与其改成C 的代码,为何不让你已有的Python 代码
    运行的更快一些呢?Psyco 是一个just-in-time(JIT)编译器,它能在运行时自动把字节码转为本地代码运行。所以,
    你只要(在运行时)导入Psyco 模块,然后告诉它要开始优化代码就可以了。而不用修改自己的代
    码。Psyco 也可以检查你代码各个部分的运行时间,以找出瓶颈所在。你甚至可以打开日志功能,来
    查看Psyco 在优化你的代码的时候,都做了些什么。你可以访问以下网站获取更多的信息:
    http://psyco.sf.net
    嵌入
    嵌入是Python 的另一功能。与把C 代码包装到Python 中的扩展相对的,嵌入是把Python 解释器包装到C 的程序中。这样做可以给大型的,单一的,要求严格的,私有的并且(或者)极其重要的应用程序内嵌Python 解释器的能力。一旦内嵌了Python,世界完全不一样了。
    Python 提供了很多官方文档供写扩展的人参考:
    扩展与嵌入
    http://docs.python.org/ext
    Python/C API
    http://docs.python.org/api
    分发Python 模块
    http://docs.python.org/dist

    [python核心编程2e.d. - 扩展Python]

    from:http://blog.csdn.net/pipisorry/article/details/49532341

    ref:python doc:Python/C API Reference Manual

    python doc: Embedding Python in Another Application

    C++中调用Python脚本

    C++调用Python

    C++调Python示例

    在VS2012中C++嵌入python

    [如何实现 C/C++ 与 Python 的通信?]*

    [Google开发了一个框架让C++和Python交互更容易]让开发者为C++程序生成Python的接口包装器


    展开全文
  • 昨天看了一下使用C语言对python进行扩展,但是死活都不成功,后来...然后今天在网上查了一下在Windows下怎么扩展python,但是也是始终无法成功,这让我相当的不爽啊,难道就因为我用的是VC++2010吗?后来实在没办法,

        昨天看了一下使用C语言对python进行扩展,但是死活都不成功,后来发现原来那个方法是Linux平台的方法,直接郁闷到了。然后今天在网上查了一下在Windows下怎么扩展python,但是也是始终无法成功,这让我相当的不爽啊,难道就因为我用的是VC++2010吗?后来实在没办法,只能去看官方的英文文档了,但是官方的扩展方法需要使用源代码,然后我就下载了源代码,转换了格式(因为官方使用的也不是VC++2010),最后确实成功了。我想这大概是属性配置的问题,于是我就粗略的在看了看官方文档,就转过头来看配置。将我自己的配置属性和源代码中例子的配置属性对比了一下,发现在连接器的命令行选项中多出了一项:/export:initexample。这个时候我意识到了很有可能就是这里的问题,经过我的验证,虽然其他的地方也有些许不同,但是没什么影响,可以肯定确实是这里的问题。激动之余,把我的发现与和我一样在使用VC2010并且想要在Windows下扩展python却始终无法实现的同志们分享一下。

        我们就来实现一个简单的扩展,定义一个叫做testMod的模块,在这个模块中包含一个对两个整数相加求和的函数和一个test函数。那么先来用C语言来实现这个函数并测试一下吧。

    #include <stdio.h>
    
    int sum(int a, int b);
    
    int main() {
        printf("2 + 3 is %d\n", sum(2, 3));
        printf("23 + 177 is %d\n", sum(23, 177));
        return 0;
    }
    
    int sum(int a, int b) {
        return a + b;
    }
        我们使用纯C语言来完成确实是轻而易举,那么现在就来讲这个C语言程序进行一番改造使之成为python的扩展吧。为了能够是C语言和python之间形成交互,我必须在C语言的源文件中加上Python.h这个头文件。接下来我们进行第二步,将函数改造成python可以调用的形式。那么怎么改造呢?我们需要使用PyObject* Module_function(PyObject *self, PyObject *args)函数将我们所需要的函数包装起来。这看着是相当的纠结啊,我们还是直接来看对sum函数的改造吧:

    int sum(int a, int b) {
        return a + b;
    }
    
    static PyObject *testMod_sum(PyObject *self, PyObject *args) {
        int a, b;
    
        if (!PyArg_ParseTuple(args, "ii", &a, &b)) {
            return NULL;
        }
    
        return (PyObject *)Py_BuildValue("i", sum(a, b));
    }

        我们现在来解释一下这段代码,首先,在C语言和python间的交互必须使用PyObject类型。其次,这个函数是返回PyObject*类型,并且以模块名加上下划线加上函数名来命名的一个函数,即:testMod_sum。在这个函数中有两个参数,第一个是self,第二个是args。虽然书上没有说明这两个参数是什么,但是大概也能猜测得到,第一个参数类似于C++中的this指针之类的东西,与python中定义一个类方法类似;第二个参数则是python传入的参数。好,继续往下看,PyArg_ParseTuple函数是干什么的?还有,"ii"又是什么?先来看PyArg_ParseTuple函数把,这个函数是用来解析从python中传入的参数并将参数的值以对应的类型传个C语言中定义的变量的。因此我们可以从这段代码中知道,args就是python中传入的参数,后面的"ii"就是对应的值的类型了,i表示整型,而ii表示有两个整型,没错,这与C语言中sscanf函数非常相似,只不过我们使用的不是%d而是使用的i,而后面则是两个整型变量的地址了。如果解析成功了,那么这个函数将会返回1,也就是真,我们将进行下一步;如果解析失败则会返回0,也就是假,这时我们则返回一个空指针。

        PyArg_ParseTuple函数很像sscanf函数,那么有没有发现Py_BuildValue函数很想prinf函数呢?没错,我们只需要这样去理解就行了。只不过Py_BuildValue函数返回的不是输出的字符个数,而是PyObject类型的指针。这个指针所指向的变量包含了我们所要传递给python的数据,在这段代码中就是a与b的和。如法炮制,我们可以将main函数改造成一个test函数。

    void test() {
        printf("2 + 3 is %d\n", sum(2, 3));
        printf("23 + 177 is %d\n", sum(23, 177));
    }
    
    static PyObject* testMod_test(PyObject *self, PyObject *args) {
        test();
        return Py_None;
    }
    

        在这段代码中PyNone表示的是空对象,也可以使用(PyObject *)Py_BuildValue("")。

        函数改造完了是不是就完了呢?不是的,我们还有其他的工作要做,我们要为模块创建一个函数列表:

    static PyMethodDef testModMethods[] = {
        {"sum", testMod_sum, METH_VARARGS},
        {"test", testMod_test, METH_VARARGS},
        {NULL, NULL}.
    };

        记得在最后加上分号,因为这是创建一个数组,不然会出错的。在这个列表中最后的{NULL, NULL}是用来表示列表已经结束了。不要急,还有最后一步了——为模块创建初始化函数,以init加上模块名作为函数名:

    void inittestMod() {
        Py_InitModule("testMod", testModMethods);
    }
    

        在初始化函数中,我们调用Py_InitModule函数来完成初始化,该函数的第一个参数是模块的名字,第二个参数是给模块的函数列表。好了,这样这个C语言源代码就改造完成了,来看一看完整的代码吧:

    #include <stdio.h>
    
    int sum(int a, int b) {
        return a + b;
    }
    
    void test() {
        printf("2 + 3 is %d\n", sum(2, 3));
        printf("23 + 177 is %d\n", sum(23, 177));
    }
    
    #include "Python.h"
    
    static PyObject* testMod_sum(PyObject *self, PyObject *args) {
        int a, b;
    
        if (!PyArg_ParseTuple(args, "ii", &a, &b)) {
            return NULL;
        }
    
        return (PyObject*)Py_BuildValue("i", sum(a, b));
    }
    
    static PyObject* testMod_test(PyObject *self, PyObject *args) {
        test();
        return Py_None;
    }
    
    static PyMethodDef testModMethods[]= {
        {"sum", testMod_sum, METH_VARARGS},
        {"test", testMod_test, METH_VARARGS},
        {NULL, NULL},
    };
    
    // 感谢@lilongduzhi的提醒,PyMODINIT_FUNC的具体定义在pyport.h文件中可以查看
    PyMODINIT_FUNC inittestMod() {
        Py_InitModule("testMod", testModMethods);
    }
    

        好了,源文件已经处理完了,值得注意的是除了模块的初始化方法不是static以外被改造的函数都必须是static。

        说明一下,我使用的是python2.7.2,安装在D:\Python27目录中,在下文中我会使用py_install_dir来替代安装目录。那么我们现在就来看看怎么创建吧。打开VC++2010,新建项目>>Win32项目>>输入testMod作为项目名>>点击确定>>下一步>>选择DLL>>点击完成。然后我们把之前的源代码粘贴到testMod.cpp中,保存。接下来就是关键了,我们要设置该项目的属性了。

        首先,将项目设置为release。然后,在项目名上点击右键并选择属性>>配置属性>>常规>>目标文件扩展名,将其改为.pyd。接着我们需要添加Python.h头文件的目录,这个文件在python的安装目录的include目录中有,因此我们只需要添加该目录即可。添加这个目录有两种方法。

    方法一:

        配置属性>>VC++目录>>包含目录,点击下拉菜单选择编辑,添加py_install_dir\include目录。记得吗?我将使用py_install_dir来代替python的安装目录。

    方法二:

        配置属性>>C/C++>>命令行,在其他选项中输入/Ipy_install_dir\include


        之前说过,我使用的python是2.7.2版本,因此我还需要向项目中加入python27.lib库,这个库位于py_install_dir\libs目录中,因此我们又有两种方法可以添加这个库。

    方法一:

        配置属性>>连接器>>常规>>附加库目录,我们只需要将py_install_dir\libs这个目录添加景区就行了。

    方法二:

        配置属性>>连接器>>命令行,在其他选项中直接添加py_install_dir\libs\python27.lib。


        最后,也是最重要的,配置属性>>连接器>>命令行>>其他选项中添加/export:模块初始化方法名,在我们所要完成的这个模块中需要添加:/export:inittestMod,否则在导入模块时出现模块为定义初始化方法的错误。


        这样项目属性就配置完成了。现在编译吧。然后找到这个项目的Release目录,将testMod.pyd文件复制或剪切到你的py_install_dir\DLLs目录之类的地方,现在打开python的解释器测试吧:


    或者通过命令行进入该项目的Release目录,打开python解释器,测试模块。


    展开全文
  • 在C++中对Python进行调用,这里以VC2008为例。  一个整体的思路就是,在这种互相调用的库或者函数中,我们做的所有事目的是让它们各自明白对方。既然PYTHON是C写的,那么它的调用肯定跟普通的LIB,DLL差不多。 ...
    在C++中对Python进行调用,这里以VC2008为例。 

        一个整体的思路就是,在这种互相调用的库或者函数中,我们做的所有事目的是让它们各自明白对方。既然PYTHON是C写的,那么它的调用肯定跟普通的LIB,DLL差不多。
    首先安装PYTHON 2.5,在VC2008的Project->Properties, C/C++和LINKER->General->additional xxx中包含对应的头文件和lib目录

        在C++代码中包含#include<Python.h>,编译看看是否正确。debug版或许会缺一个xx_d.lib的调试文件,这个只要将原来版本的lib修改一下即可。

    1. 既然是调用python,就先用python写个函数   
    2. #callByC++.py   
    3.   
    4. def Hello():   
    5.     print 'hello callByC++'  
    既然是调用python,就先用python写个函数
    #callByC++.py
    
    def Hello():
        print 'hello callByC++'


    就下来就要考虑在哪个地方编译它.python已经提供了完善的模块接口,在C++代码里把这事干掉。
    首先得让C++认到该文件,将该文件移到你的工程目录下,
    接着在代码中键入如下:

    1. int _tmain(int argc, _TCHAR* argv[])   
    2. {   
    3.      Py_Initialize();           //使用python之前,要调用Py_Initialize();这个函数进行初始化  
    4.      PyObject * pModule = NULL; //声明变量   
    5.      PyObject * pFunc = NULL;       //声明变量  
    6.      pModule =PyImport_ImportModule("helloworld");  //这里是要调用的文件名  
    7.      pFunc= PyObject_GetAttrString(pModule, "Hello"); //这里是要调用的函数名  
    8.      PyEval_CallObject(pFunc, NULL);            //调用函数  
    9.      Py_Finalize();                     //调用Py_Finalize,这个跟Py_Initialize相对应的。  
    10.      return 0;   
    11. }  
    int _tmain(int argc, _TCHAR* argv[])
    {
         Py_Initialize();			//使用python之前,要调用Py_Initialize();这个函数进行初始化
         PyObject * pModule = NULL;	//声明变量
         PyObject * pFunc = NULL;		//声明变量
         pModule =PyImport_ImportModule("helloworld");	//这里是要调用的文件名
         pFunc= PyObject_GetAttrString(pModule, "Hello"); //这里是要调用的函数名
         PyEval_CallObject(pFunc, NULL);			//调用函数
         Py_Finalize();						//调用Py_Finalize,这个跟Py_Initialize相对应的。
         return 0;
    }

    运行完后,你会发现,你的py文件已经自动编译成pyc了.如果想移动你的exe,记得带上pyc


    在Python中对C++进行调用


        参考PYTHON引入其他模块的语法,import *,无头文件概念。可以推出在dll的编译中必须以python的数据类型来进行代码的编写。新建一个DLL工程,在头文件和库文件的路径中设置好python的目录。关于DLL的创建其实很简单,回到开头所说的,我们做的事都是让它们各自明白对方。而dll的编制只不过在你用VC写完代码,按下F5时的整体工作中的一个步骤。如果写过LINUX的MAKEFILE人都明白,每个指定的C或者CPP文件都要编译成一个obj类型,然后主文件根据头文件的申明符号,去这些OBJ中寻找自己的函数代码,最后综合产生出二进制代码。所以说在DLL中做的事也一样,只要注意下他的格式说明。
        在为python写DLL的时候,必须有个initXX(XX表示你的DLL名字)函数。生成完后改名为.pyd。


    1. static PyObject* mb_showMsg(PyObject* self, PyObject *args);   
    2.   
    3. extern "C" __declspec(dllexport) void initmb()              //注意这里的名字  
    4. {   
    5.     static PyMethodDef mbMethods[] = {                  //python无法直接用mb_showMsg访问  
    6.         {"showMsg", mb_showMsg, METH_VARARGS},   
    7.         {NULL, NULL, NULL} /*sentinel,哨兵,用来标识结束*/  
    8.     };     
    9.   
    10.     PyObject *m = Py_InitModule("mb", mbMethods);             //"mb"是你外部的文件名  
    11. }   
    12.   
    13. static PyObject* mb_showMsg(PyObject* self, PyObject *args)   
    14. {   
    15.     //我们的showMsg函数需要的是一个字符串参数   
    16.     const char* msg = NULL;   
    17.     LPWSTR wmsg = NULL;   
    18.        
    19.     if (!PyArg_ParseTuple(args, "s", &msg))   
    20.         return NULL;   
    21.   
    22.     int r;   
    23.     DWORD dwNum = MultiByteToWideChar (CP_ACP, 0, msg, -1, NULL, 0); //宽字符的转换,我的VC环境默认是UNICODE  
    24.     wmsg = new wchar_t[dwNum];   
    25.   
    26.     if(!wmsg)   
    27.     {   
    28.       delete []wmsg;   
    29.       r = ::MessageBox(NULL, _T("conversion failed") , _T("Caption:Form C module"), MB_ICONINFORMATION | MB_OK);   
    30.     }   
    31.     else  
    32.     {   
    33.         MultiByteToWideChar (CP_ACP, 0, msg, -1, wmsg, dwNum);   
    34.         //调用MB   
    35.         r = ::MessageBox(NULL, wmsg , _T("Caption:Form C module"), MB_ICONINFORMATION | MB_OK);   
    36.         delete []wmsg ;        
    37.     }   
    38.   
    39.     //返回值   
    40.     return Py_BuildValue("i", r);   
    41. }  
    static PyObject* mb_showMsg(PyObject* self, PyObject *args);
    
    extern "C" __declspec(dllexport) void initmb()				//注意这里的名字
    {
    	static PyMethodDef mbMethods[] = {					//python无法直接用mb_showMsg访问
    		{"showMsg", mb_showMsg, METH_VARARGS},
    		{NULL, NULL, NULL} /*sentinel,哨兵,用来标识结束*/
    	};	
    
    	PyObject *m = Py_InitModule("mb", mbMethods);		      //"mb"是你外部的文件名
    }
    
    static PyObject* mb_showMsg(PyObject* self, PyObject *args)
    {
        //我们的showMsg函数需要的是一个字符串参数
        const char* msg = NULL;
    	LPWSTR wmsg = NULL;
    	
    	if (!PyArg_ParseTuple(args, "s", &msg))
            return NULL;
    
    	int r;
    	DWORD dwNum = MultiByteToWideChar (CP_ACP, 0, msg, -1, NULL, 0); //宽字符的转换,我的VC环境默认是UNICODE
    	wmsg = new wchar_t[dwNum];
    
    	if(!wmsg)
    	{
    	  delete []wmsg;
    	  r = ::MessageBox(NULL, _T("conversion failed") , _T("Caption:Form C module"), MB_ICONINFORMATION | MB_OK);
    	}
    	else
    	{
    		MultiByteToWideChar (CP_ACP, 0, msg, -1, wmsg, dwNum);
    		//调用MB
    		r = ::MessageBox(NULL, wmsg , _T("Caption:Form C module"), MB_ICONINFORMATION | MB_OK);
    		delete []wmsg ;		
    	}
    
        //返回值
        return Py_BuildValue("i", r);
    }


    最后就可以“品尝”下最后的结果了。把dll文件拷到python目录的dlls下。名字改成mb.pyd.在python交互器中这么写

    1. import mb   
    2. mb.showMsg("lin_style");  
    import mb
    mb.showMsg("lin_style");



    参考 http://hi.baidu.com/wenlongren/blog/item/c17eb0dae80844deb7fd48e7.html
    参考http://blog.sina.com.cn/s/blog_4f927ca70100aeor.html
    展开全文
  • 1. 首先VC++的DLL的导出函数定义成标准C的导出函数: #ifdefLRDLLTEST_EXPORTS #defineLRDLLTEST_API__declspec(dllexport) #else #defineLRDLLTEST_API__declspec(dllimport) #endif extern"C"LRDLLT...

    1. 首先VC++的DLL的导出函数定义成标准C的导出函数:


    复制代码
    #ifdef LRDLLTEST_EXPORTS
    #
    define LRDLLTEST_API __declspec(dllexport)
    #
    else
    #
    define LRDLLTEST_API __declspec(dllimport)
    #
    endif

    extern 
    "C" LRDLLTEST_API int Sum(int a , int b);
    extern 
    "C" LRDLLTEST_API void GetString(char* pChar);

    //+ b
    LRDLLTEST_API int Sum(int a , int b)
    {
        
    return a + b;
    }

    //Get a string
    LRDLLTEST_API void GetString(char
    * pChar)
    {
        strcpy(pChar, 
    "Hello DLL");
    }
    复制代码


    2. Python中调用如下:


    复制代码
    from ctypes import *

    fileName
    ="LRDllTest.dll"
    func
    =cdll.LoadLibrary(fileName)
    str 
    = create_string_buffer(20)
    = func.Sum(23)
    func.GetString(str)

    print n
    print str.raw
    复制代码


    关于C语言中的一些参数类型详见:http://www.python.org/doc/2.5/lib/node454.html

    3. 输出结果:


    5
    Hello DLL


     

    Python 天天美味系列(总)

    Python 天天美味(27) - 网络编程起步(Socket发送消息)  

    Python 天天美味(28) - urlopen    

    Python 天天美味(29) - 调用VC++的动态链接库(DLL) 

    Python 天天美味(30) - python数据结构与算法之快速排序 

    Python 天天美味(31) - python数据结构与算法之插入排序 

    ...



    本文转自CoderZh博客园博客,原文链接:http://www.cnblogs.com/coderzh/archive/2008/07/23/1249919.html,如需转载请自行联系原作者

    展开全文
  • VC++ for Python2.7

    2020-06-03 23:32:54
    VC++ for Python2.7, 貌似在官网不好下载,所以就在这里分享一下啦 链接: https://pan.baidu.com/s/1cD7IGm 密码: juig
  • 大家都知道Python的优点是开发效率高,使用方便,C++则是运行效率高,这两者可以相辅相成,不管是在Python项目中嵌入C++代码,或是在C++项目中用Python实现外围功能,都可能遇到Python调用C++模块的需求,下面列举出...

    参考:https://www.jb51.net/article/104159.htm

    0 前言

    大家都知道Python的优点是开发效率高,使用方便,C++则是运行效率高,这两者可以相辅相成,不管是在Python项目中嵌入C++代码,或是在C++项目中用Python实现外围功能,都可能遇到Python调用C++模块的需求,下面列举出集中c++代码导出成Python接口的几种基本方法,一起来学习学习吧。

    1 原生态导出

    Python解释器就是用C实现,因此只要我们的C++的数据结构能让Python认识,理论上就是可以被直接调用的。我们实现test1.cpp如下

    #include <Python.h> 
      
    int Add(int x, int y) 
    { 
     return x + y; 
    } 
      
    int Del(int x, int y) 
    { 
     return x - y; 
    } 
      
    PyObject* WrappAdd(PyObject* self, PyObject* args) 
    { 
     int x, y; 
     if (!PyArg_ParseTuple(args, "ii", &x, &y)) 
     { 
      return NULL; 
     } 
     return Py_BuildValue("i", Add(x, y)); 
    } 
      
    PyObject* WrappDel(PyObject* self, PyObject* args) 
    { 
     int x, y; 
     if (!PyArg_ParseTuple(args, "ii", &x, &y)) 
     { 
      return NULL; 
     } 
     return Py_BuildValue("i", Del(x, y)); 
    } 
    static PyMethodDef test_methods[] = { 
     {"Add", WrappAdd, METH_VARARGS, "something"}, 
     {"Del", WrappDel, METH_VARARGS, "something"}, 
     {NULL, NULL} 
    }; 
      
    extern "C"
    void inittest1() 
    { 
     Py_InitModule("test1", test_methods); 
    }
    

    编译命令如下

    g++ -fPIC -shared test1.cpp -I/usr/include/python2.7 -o test1.so 
    

    -fPIC:生成位置无关目标代码,适用于动态连接;
    -L path:表示在path目录中搜索库文件,如-L.表示在当前目录;
    -I path:表示在path目录中搜索头文件;
    -o file:制定输出文件为file;
    -shared:生成一个共享库文件;

     运行Python解释器,测试如下

    >>> import test1 
    >>> test1.Add(1,2) 
    3 
    

    这里要注意一下几点

    1. 如果生成的动态库名字为test1,则源文件里必须有inittest1这个函数,且Py_InitModule的第一个参数必须是“test1”,否则Python导入模块会失败
    2. 如果是cpp源文件,inittest1函数必须用extern "C"修饰,如果是c源文件,则不需要。原因是Python解释器在导入库时会寻找initxxx这样的函数,而C和C++对函数符号的编码方式不同,C++在对函数符号进行编码时会考虑函数长度和参数类型,具体可以通过nm test1.so查看函数符号,c++filt工具可通过符号反解出函数原型

    2 通过boost实现

    我们使用和上面同样的例子,实现test2.cpp如下

    #include <boost/python/module.hpp> 
    #include <boost/python/def.hpp> 
    using namespace boost::python; 
      
    int Add(const int x, const int y) 
    { 
     return x + y; 
    } 
      
    int Del(const int x, const int y) 
    { 
     return x - y; 
    } 
      
    BOOST_PYTHON_MODULE(test2) 
    { 
     def("Add", Add); 
     def("Del", Del); 
    }
    

    其中BOOST_PYTHON_MODULE的参数为要导出的模块名字,编译命令如下

    g++ test2.cpp -fPIC -shared -o test2.so -I/usr/include/python2.7 -I/usr/local/include -L/usr/local/lib -lboost_python 
    

    注意: 编译时需要指定boost头文件和库的路径,我这里分别是/usr/local/include和/usr/local/lib

    或者通过setup.py导出模块

    #!/usr/bin/env python 
    from distutils.core import setup 
    from distutils.extension import Extension 
      
    setup(name="PackageName", 
     ext_modules=[ 
      Extension("test2", ["test2.cpp"], 
      libraries = ["boost_python"]) 
     ])
    

    Extension的第一个参数为模块名,第二个参数为文件名

    执行如下命令

    python setup.py build 
    

    这时会生成build目录,找到里面的test2.so,并进入同一级目录,验证如下

    >>> import test2 
    >>> test2.Add(1,2) 
    3
    >>> test2.Del(1,2) 
    -1 
    

    3 导出类

    test3.cpp实现如下

    #include <boost/python.hpp> 
    using namespace boost::python; 
      
    class Test 
    { 
    public: 
     int Add(const int x, const int y) 
     { 
      return x + y; 
     } 
      
     int Del(const int x, const int y) 
     { 
      return x - y; 
     } 
    }; 
      
    BOOST_PYTHON_MODULE(test3) 
    { 
     class_<Test>("Test") 
      .def("Add", &Test::Add) 
      .def("Del", &Test::Del); 
    }
    

    注意:BOOST_PYTHON_MODULE里的.def使用方法有点类似Python的语法,等同于

    class_<Test>("Test").def("Add", &Test::Add); 
    class_<Test>("Test").def("Del", &Test::Del); 
    

    编译命令如下

    g++ test3.cpp -fPIC -shared -o test3.so -I/usr/include/python2.7 -I/usr/local/include/boost -L/usr/local/lib -lboost_python 
    

    测试如下

    >>> import test3 
    >>> test = test3.Test() 
    >>> test.Add(1,2) 
    3
    >>> test.Del(1,2) 
    -1 
    

    4 导出变参函数

    test4.cpp实现如下

    #include <boost/python.hpp> 
    using namespace boost::python; 
      
    class Test 
    { 
    public: 
     int Add(const int x, const int y, const int z = 100) 
     { 
      return x + y + z; 
     } 
    }; 
      
    int Del(const int x, const int y, const int z = 100) 
    { 
     return x - y - z; 
    } 
      
    BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(Add_member_overloads, Add, 2, 3) 
    BOOST_PYTHON_FUNCTION_OVERLOADS(Del_overloads, Del, 2, 3) 
      
    BOOST_PYTHON_MODULE(test4) 
    { 
     class_<Test>("Test") 
      .def("Add", &Test::Add, Add_member_overloads(args("x", "y", "z"), "something")); 
     def("Del", Del, Del_overloads(args("x", "y", "z"), "something")); 
    }
    

    这里Add和Del函数均采用了默认参数,Del为普通函数,Add为类成员函数,这里分别调用了不同的宏,宏的最后两个参数分别代表函数的最少参数个数和最多参数个数

    编译命令如下

    g++ test4.cpp -fPIC -shared -o test4.so -I/usr/include/python2.7 -I/usr/local/include/boost -L/usr/local/lib -lboost_python 
    

    测试如下

    >>> import test4 
    >>> test = test4.Test() 
    >>> print test.Add(1,2) 
    103
    >>> print test.Add(1,2,z=3) 
    6
    >>> print test4.Del(1,2) 
    -1
    >>> print test4.Del(1,2,z=3) 
    -1
    

    5 导出带Python对象的接口

    既然是导出为Python接口,调用者难免会使用Python特有的数据结构,比如tuple,list,dict,由于原生态方法太麻烦,这里只记录boost的使用方法,假设要实现如下的Python函数功能

    def Square(list_a) 
    { 
     return [x * x for x in list_a] 
    }
    

    即对传入的list每个元素计算平方,返回list类型的结果,代码如下

    #include <boost/python.hpp> 
      
    boost::python::list Square(boost::python::list& data) 
    { 
     boost::python::list ret; 
     for (int i = 0; i < len(data); ++i) 
     { 
      ret.append(data[i] * data[i]); 
     } 
      
     return ret; 
    } 
      
    BOOST_PYTHON_MODULE(test5) 
    { 
     def("Square", Square); 
    }
    

    编译命令如下

    g++ test5.cpp -fPIC -shared -o test5.so -I/usr/include/python2.7 -I/usr/local/include/boost -L/usr/local/lib -lboost_python 
    

    测试如下

    >>> import test5 
    >>> test5.Square([1,2,3]) 
    [1, 4, 9] 
    

    boost实现了boost::python::tuple, boost::python::list, boost::python::dict这几个数据类型,使用方法基本和Python保持一致,具体方法可以查看boost头文件里的boost/python/tuple.hpp及其它对应文件

    另外比较常用的一个函数是boost::python::make_tuple() ,使用方法如下

    boost::python::tuple(int a, int b, int c) 
    {  
        return boost::python::make_tuple(a, b, c); 
    } 
    

     

    展开全文
  • vc调用python

    2017-03-01 15:14:20
    首先下载python的开发包,到百度上搜pyhon msi下载,会有相关下载链接,比如http://download.csdn.net/download/w277608109/8299309。 不能下exe的执行程序,那里面没有相关的头文件,比如pyhon.h。 pyhon官网上也有...
  • C++调用Python实例

    2017-02-15 14:41:28
    C++调用Python方法基本有以下几个步骤: 1、下载Python; 2、配置信息(本次我用的配置是VS2013+Python36),注意Python请下载32位的版本(即使你的操作系统是64位的),否则会函数未定义的错误 3、把Python加到VS...
  • **问题: python如何调用Qt带有GUI模块的DLL?** <br/> **本人的探索:** * python可以正常调用VC带UI的DLL. * 网上资料建议在可执行程序下,加入Qt5.5.1/5.5/mingw492_32的platforms和plugins目录下...
  • 最近有个项目需要使用到python调用C++编写动态连接库 无奈在百度上的办法百花齐放 跟着做也频频出错 所以自己研究了一下调用的规则 ————————————下面是正文—————————————— 一.环境...
  • 最近项目中需要使用vc++调用gp工具,在网上查查发现用。net和python调用很简单,但是在vc中没有响应的工具类,只用通过gp接口指定工具名称来执行代码,现在把调用代码给大家:
  • 使用VC++2010扩展python

    2012-10-09 15:04:22
    使用VC++2010扩展python 简介:这里介绍使用VC2010编译C语言编写的python扩展模块,hdlc模块。Hdlc是高级数据链路控制(High-LevelData Link Control或简称HDLC),用于无界流数据上确保用户数据包的完整性。该...
  • C++调用python (2.7版本) (Win7_64 + VS2013 + python2.7)  由于个人偏好喜欢用python写代码,尤其是数据处理等,最近想试试在VS2013里,直接调用python中的曲线拟合函数。作为小白,由于之前完全没接触过,...
  • 本文讲解关于在C++中调用python的环境配置和简单函数功能实现,废话就不赘述了。 一、首先环境配置 1.创建控制台应用程序testpy,新建源文件main.cpp 2.进入属性管理器,右击项目,选择属性。(也可以新建项目...
  • 1、java调用Python(无参数)#coding:utf-8 def sum(): print "hello world" if __name__ == '__main__': sum()package com; import java.io.BufferedReader; import java.io.InputStreamReader; public...
  • VS2010调用python

    2019-08-13 16:49:27
    1.VS2010配置 VC++ Directories->Include Directories中添加**/python/include文件; VC++ Directories->Library Directories中添加**/python/libs文件; 注意最好配置的32位python,配置成64位的python运行...
  • 本例没有使用boost库,你也可以使用boost库来改进代码
  • 环境:win7-64位VS2013python-2.7.8-32位 (得用32位,这很重要)boost.python-1.57步骤:一. “安装”boost.python解压boost.python后,用VS的[本机命令提示工具](开始-VS2013-VS Tools)进入到boost的文件夹,...
1 2 3 4 5 ... 20
收藏数 3,771
精华内容 1,508
关键字:

2010 python vc++ 调用