设为首页 加入收藏

TOP

工程脚本插件方案 - c集成Python基础篇(二)
2017-10-12 17:39:21 】 浏览:3597
Tags:工程 脚本 插件 方案 集成 Python 基础
N... >>>

创建hello.c

在工程中添加一个新文件,命名为hello.c。复制下面内容。

//
// C code runs Python code in this module in embedded mode.
// print hello string
// 
// www.moguf.com  2016-05-28
//

#include <python.h>

int main()
{
    Py_Initialize();

    PyRun_SimpleString("print('run python ...')");
    PyRun_SimpleString("import script");
    PyRun_SimpleString("print(script.message)");
    PyRun_SimpleString("x = script.message");
    PyRun_SimpleString("print(script.transform(x))");

    Py_Finalize();
}

运行程序

在程序最后下个断点,方便查看运行结果。直接运行程序可以看到下面结果。

run python ...
hello life...
HELLO PYTHON...

基本调用流程解析

使用C程序运行Python脚本代码,可以通过使用Python字符串,调用Python对象或模板之类的所有操作。

流程:
1、初始化Python解析器
2、执行Python代码,字符串,对象或模块。
3、关闭Python解析器。

上面代码嵌入过程很容易。但在实际使用中想要更好的整合,须要了解提供的API和不同语言之间的转换。

Python嵌入C的基础API

下面几个基础API,在C中能很容易的执行Python脚本中的代码。包括字典、数组和对象。当然想要更好的混合交互须要熟悉所有的API。

C API 调用 Python 对应
PyImport_ImportModel import module
PyImport_ReloadModule reload(module)
PyImport_GetModuleDict module.__dict__
PyDict_GetItemString dict[key]
PyDict_SetItemString dict[key] = value
PyDict_New dict = {}
PyObject_GetAttrString getattr(obj, attr)
PyObject_SetAttrString setattr(obj, attr, val)
PyObject_CallObject funcobj(*argstuple)
Pyeva l_CallObject funcobj(*argstuple)
PyRun_String eva l(exprstr) , exec(stmtstr)
PyRun_File exec(open(filename().read())

建议: 去官网下载一个手册,方便查看API。https://docs.python.org/3/download.html

2.2、使用C扩展Python

2.1的内容只是通过C程序调用Python脚本,要让Python脚本能调用C代码,就须要扩展。用C扩展Python功能那就简单很多。有很多实例可以参考。Python源代码就是宝库。

创建扩展工程 hello

在VS中创建一个空的动态库hello工程(先不要改名)。在工程配置中增加搜索路径。

在VS生成时有些特殊。生成的后缀选择.pyd主要是为防止和系统.dll产生冲突。

在工程选项界面中设置工程输出名称为$(ProjectName)_d,输出扩展名称为.pyd

并在Linker页面Input组中设置库依赖为python35_d.lib

不同的编译模式的设置:
Release 下使用的依赖库为pythonXY.lib
Debug 下使用依赖库为 pythonXY_d.lib

注意:
debug 模式生成应为 hello_d.pyd
release 模式生成应为 hello.pyd

创建hello.c扩展代码

在工程中新建hello.c文件,复制下面内容。

//
// A simple C extension module for python, called "hello"
// 
// www.moguf.com  2016-05-28
//

#include <python.h>
#include <string.h>

//
// module functions
//
static PyObject *                                 // returns object
message(PyObject *self, PyObject *args)           
{                                                 
    char *fromPython, result[1024];
    if (!PyArg_Parse(args, "(s)", &fromPython))  // convert Python -> C 
        return NULL;                             //  exception null = raise 
    else {
        strcpy(result, "Hello , ");                // build up C string
        strcat(result, fromPython);               // add passed Python string 
        return Py_BuildValue("s", result);        // convert C -> Python 
    }
}

//
// registration methods table 
static PyMethodDef hello_methods[] = {
    { "message",  message, METH_VARARGS, "func doc" },    // format: name, &func, fmt, doc 

    { NULL, NULL, 0, NULL }                               // end
};

// module definition structure
static struct PyModuleDef hellomodule = {
    PyModuleDef_HEAD_INIT,
    "hello",         // module name
    "mod doc",       // module documentation,
    -1,              
    hello_methods    // methods table
};

//
// module initializer
PyMODINIT_FUNC
PyInit_hello()                         
{                                      
    return PyModule_Create(&hellomodule);
}

上面的代码主要分为四块。

第一块: 模块功能实现函数
第二块: 注册功能函数
第三块: 定义模块申明
第四块: 初始化模块。动态加载就不需要这块内容,集成时会使用动态加载。

通过上述定义为Python脚本调用提供访问入口,这就是通常所说的胶水代码。具体定义直接看代

首页 上一页 1 2 3 4 下一页 尾页 2/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇关于 OJ1574的参考题解(较麻烦) 下一篇二项展开式的系数

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目