博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python C API的使用详解(一)
阅读量:7019 次
发布时间:2019-06-28

本文共 7378 字,大约阅读时间需要 24 分钟。

简介

介绍一下Python虚拟机的初始化及退出,Python基本数据类型的对象创建以及C和Python之间的数据类型互相转换。

Python虚拟机的初始化及退出

初始化Python虚拟机需要调用Py_Initialize()来实现。

Py_IsInitialized()用于判断Python虚拟机初始化是否成功,True是成功,False是失败。

C/C++中调用Python之前必须先初始化虚拟机。

退出虚拟机的时候调用Py_Finalize()

进程退出时要退出Python虚拟机。

实例:

#include 
#include
using namespace std;int main() { // 初始化Python虚拟机 Py_Initialize(); // 判断Python虚拟机是否成功 if (Py_IsInitialized() == 0){ printf("fal to initialize Python\n"); return -1; } printf("server start\n"); // 退出Python虚拟机 Py_Finalize(); return 0;}

编译方式及参数:

下面是Python2的编译方式,Python3的话,只需要将Python的库路径改成Python3的即可g++ -I/usr/include/python2.7 -c main.cppg++ -o main main.o -L/usr/local/lib -lpython2.7 -lrt -lpthread -lutil -ldl

PyObject

Python的所有对象类型都是此类型的扩展。 这是一种类型,它包含Python将对象的指针视为对象所需的信息。 在正常的“发布”版本中,它仅包含对象的引用计数和指向相应类型对象的指针。 实际上没有任何东西被声明为PyObject,但是每个指向Python对象的指针都可以转换为PyObject *。 必须使用宏Py_REFCNT和Py_TYPE来访问成员。

宏描述,不包括全部

Py_TYPE:  获取Python对象的数据类型Py_REFCNT: Python的引用计数器Py_SIZE:  获取Python数据大小还有很多...

Py_BuildValue

可以使用其将C的所有基本数据类型转换成Python可访问的数据类型。

标识符介绍:

s(str或None)[char *]使用'utf-8'编码将以null结尾的C字符串转换为Python str对象。如果C字符串指针为NULL,则表示None。s#(str或None)[char *,int]使用'utf-8'编码将C字符串及其长度转换为Python str对象。如果C字符串指针为NULL,则忽略长度返回None。y(字节)[char *]这会将C字符串转换为Python字节对象。如果C字符串指针为NULL,则返回None。y#(字节)[char *,int]这会将C字符串及其长度转换为Python对象。如果C字符串指针为NULL,则返回None。z(str或None)[char *]与s相同。z#(str或None)[char *,int]与s#相同。u(str)[Py_UNICODE *]将Unicode(UCS-2或UCS-4)数据的以null结尾的缓冲区转换为Python Unicode对象。如果Unicode缓冲区指针为NULL,则返回None。u#(str)[Py_UNICODE *,int]将Unicode(UCS-2或UCS-4)数据缓冲区及其长度转换为Python Unicode对象。如果Unicode缓冲区指针为NULL,则忽略长度并返回None。U(str或None)[char *]与s相同。U#(str或None)[char *,int]与s#相同。i(int)[int]将普通的C int转换为Python整数对象。b(int)[char]将纯C char转换为Python整数对象。h(int)[short int]将普通的C short int转换为Python整数对象。l(int)[long int]将C long int转换为Python整数对象。B(int)[unsigned char]将C unsigned char转换为Python整数对象。H(int)[unsigned short int]将C unsigned short int转换为Python整数对象。I(int)[unsigned int]将C unsigned int转换为Python整数对象。k(int)[unsigned long]将C unsigned long转换为Python整数对象。L(int)[long long]将C long long转换为Python整数对象。K(int)[unsigned long long]将C unsigned long long转换为Python整数对象。n(int)[Py_ssize_t]将C Py_ssize_t转换为Python整数。c(长度为1的字节)[char]将表示字节的C int转换为长度为1的Python字节对象。C(长度为1的str)[int]将表示字符的C int转换为长度为1的Python str对象。d(float) [double] 将C double转换为Python浮点数。f(float) [float] 将C float转换为Python浮点数。D(complex) [Py_complex *]将C Py_complex结构转换为Python复数。O(object) [PyObject *]不改变Python对象的传递(引用计数除外,它增加1)。如果传入的对象是NULL指针,则假定这是因为产生参数的调用发现错误并设置了异常。因此,Py_BuildValue()将返回NULL但不会引发异常。如果尚未引发异常,则设置SystemError。S(object) [PyObject *]与O相同N((object) [PyObject *]与O相同,但不会增加对象的引用计数。通过调用参数列表中的对象构造函数创建对象时很有用。O&(object) [converter, anything] 通过转换器函数将任何内容转换为Python对象。该函数被调用任何东西(应与void *兼容)作为其参数,并应返回“新”Python对象,如果发生错误则返回NULL。(items) (tuple) [matching-items] 将一系列C值转换为具有相同项目数的Python元组。[items](list) [matching-items]将一系列C值转换为具有相同项目数的Python列表。{items}(dict) [matching-items] 将一系列C值转换为Python字典。每对连续的C值将一个项添加到字典中,分别用作键和值。如果格式字符串中存在错误,则设置SystemError异常并返回NULL。

创建整型的Python对象

使用Py_BuildValue创建整型对象。

void int_object(){    // 第一种方式    PyObject *py_ival = Py_BuildValue("i", -5987);   // Python有符号整型    PyObject *py_ival2 = PyLong_FromLong(-8979);    int ival = PyLong_AsLong(py_ival);   // 把Python有字符整型转换成C的有字符整型    int ival2 = PyLong_AsLong(py_ival2);   // 把Python有字符整型转换成C的有字符整型    printf("ival = %d, ival2 = %d\n", ival, ival2);    // 第二种方式    PyObject *py_uval = Py_BuildValue("I", 465486);   // Python无符号整型    PyObject *py_uval2 = PyLong_FromUnsignedLong(1654864);    unsigned int uval = PyLong_AsUnsignedLong(py_uval);        // 把Python无字符整型转换成C的无字符整型    unsigned int uval2 = PyLong_AsUnsignedLong(py_uval2);        // 把Python无字符整型转换成C的无字符整型    printf("uval = %u, uval2 = %u\n", uval, uval2);}

创建长整型的Python对象

void long_object(){    // 第一种方式    PyObject *py_lval = Py_BuildValue("L", 45648946484984);   // Python 长整型    long long c_lval = PyLong_AsLongLong(py_lval);   // 转换成C的长整型    printf("clval = %lld\n", c_lval);    // 第二种方式    PyObject *py_lval2 = PyLong_FromLongLong(234234623454525);   // PyLong_FromLongLong 使用方法定义一个Python长整型    long long c_lval2 = PyLong_AsLongLong(py_lval2);   // 转换成C的长整型    printf("clval2 = %lld\n", c_lval2);}

创建浮点类型的Python对象

void double_object(){    // 第一种方式    float fval = 632.045;    PyObject *py_fval = Py_BuildValue("d", fval);   // Python 浮点类型    float c_fval = PyFloat_AsDouble(py_fval);    // C的浮点类型    printf("fval = %f\n", c_fval);    // 第二种方式    double  dval = 48941546.578;    PyObject *py_dval = PyFloat_FromDouble(dval);   // Python 浮点类型    double c_dval = PyFloat_AsDouble(py_dval);   // C的浮点类型    printf("c_dval = %lf\n", c_dval);}

创建布尔类型对象

void boolean_object(){    // 第一种方式    bool bval = true;   // false 反之    PyObject *py_bval = Py_BuildValue("b", bval);   // Python 布尔类型    int c_bval = PyInt_AsLong(py_bval);    printf("c_bval = %d\n", c_bval);    // 第二种方式    bool bval2 = false;    PyObject *py_bval2 = PyBool_FromLong(bval2);   // Python 布尔类型    int c_bval2 = PyInt_AsLong(py_bval2);    printf("c_bval2 = %d\n", c_bval2);}

创建Python string对象

void string_object(){    // 第一种方式    const char *pstr = "this is a test";    PyObject *py_str = Py_BuildValue("s", pstr);   // Python 字符串对象    char *c_pstr = PyString_AsString(py_str);   // 转成C的字符指针    printf("c_pstr = %s\n", c_pstr);    // 第二种方式    const char *pstr2 = "this is a test1";    PyObject *py_str2 = PyString_FromString(pstr2);   // Python 字符串对象    char *c_pstr2 = PyString_AsString(py_str2);   // 转成C的字符指针    printf("c_pstr2 = %s\n", c_pstr2);    // 创建一个二进制的字符串对象    // 第一种方式    const int mem_len = 1024;    char *mem = new char[mem_len];    PyObject *py_mem = Py_BuildValue("s#", mem, mem_len);  // 1. 数据的类型 2. 指向数据的指针 3. 数据的长度    int c_data_len = PyString_Size(py_mem);    printf("c_data_len = %d\n", c_data_len);    // 第二种方式    PyObject *py_mem2 = PyString_FromStringAndSize(mem, mem_len);    int c_data_len2 = PyString_Size(py_mem2);    printf("c_data_len2 = %d\n", c_data_len2);}

创建unicode字符串对象

void unicode_object(){    const char *p_ustr = "兰玉磊";    PyObject *py_unicode = PyUnicode_FromString(p_ustr);  // 把C的字符串转成Python的unicode    // 把unicode转成C的字符串    PyObject *py_utf8 = PyUnicode_AsUTF8String(py_unicode);   // 把unicode转成utf-8    const char *c_string = PyString_AsString(py_utf8);   // 把utf-8转成c的字符串    printf("c_utf8 = %s\n", c_string);    // 格式化unicode字符串    // 创建一个unicode字符串    PyObject *py_unicode_fmt = PyUnicode_FromFormat("%s%d%s", "我今年", 18, "岁");    // 把unicode转C字符串    PyObject *py_utf8_fmt = PyUnicode_AsUTF8String(py_unicode_fmt);    const char *utf8_fmt = PyString_AsString(py_utf8_fmt);    printf("utf8_fmt = %s\n", utf8_fmt);}

使用Py_None

Py_None是一个全局的变量

PyObject* none_object(){    Py_RETURN_NONE;   // 不需要自己return}

main函数

#include 
#include
#include
#include
int main() { // 初始化Python虚拟机 Py_Initialize(); // 判断Python虚拟机是否成功 if (Py_IsInitialized() == 0){ printf("fal to initialize Python\n"); return -1; } printf("server start\n"); int_object(); long_object(); double_object(); boolean_object(); string_object(); unicode_object(); PyObject *py_ret = none_object(); if (py_ret == Py_None){ printf("is none object\n"); }else{ printf("is not none object\n"); } // 退出Python虚拟机 Py_Finalize(); return 0;}

转载于:https://blog.51cto.com/11293981/2167897

你可能感兴趣的文章
云上自动化:全球云上自动化编排系统比拼
查看>>
解读AI行业发展趋势
查看>>
嵌入式开发培训都要学什么?零基础参加嵌入式学习培训能学会吗
查看>>
flume的初体验
查看>>
hbase的基本操作
查看>>
DevOps工程师到底做些什么?
查看>>
解析RDD在Spark中的地位
查看>>
高质量SEO文章编辑规范技巧之:格式
查看>>
Liunx磁盘存储和文件系统
查看>>
人工智能在4S店、网店,应用经验分享
查看>>
linux下清空mysql密码
查看>>
Oracle 11g r2数据泵新特性(五)
查看>>
oracle技术之Rman备份恢复命令
查看>>
COBBLER无人值守安装
查看>>
解决golang.org/x包无法下载的问题
查看>>
ansible puppet saltstack三款自动化运维工具的对比
查看>>
PHP - windows下编译PHP 7.1的memcache
查看>>
手机互动网页项目总结(转)
查看>>
SAPCAR简单使用
查看>>
shell脚本每天自动备份mysql数据库
查看>>