返回顶部
首页 > 资讯 > 后端开发 > Python >Python C API的使用详解(一)
  • 184
分享到

Python C API的使用详解(一)

详解PythonAPI 2023-01-31 06:01:55 184人浏览 独家记忆

Python 官方文档:入门教程 => 点击学习

摘要

简介 介绍一下python虚拟机的初始化及退出,Python基本数据类型的对象创建以及C和Python之间的数据类型互相转换。 Python虚拟机的初始化及退出 初始化Python虚拟机需要调用Py_Initialize()来实现。 Py_

简介

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

Python虚拟机的初始化及退出

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

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

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

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

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

实例:

#include <stdio.h>
#include <Python.h>
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.cpp
g++ -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 <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <Python.h>
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;
}

--结束END--

本文标题: Python C API的使用详解(一)

本文链接: https://lsjlt.com/news/189798.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Python C API的使用详解(一)
    简介 介绍一下Python虚拟机的初始化及退出,Python基本数据类型的对象创建以及C和Python之间的数据类型互相转换。 Python虚拟机的初始化及退出 初始化Python虚拟机需要调用Py_Initialize()来实现。 Py_...
    99+
    2023-01-31
    详解 Python API
  • Python C API 使用详解(二)
    简介 介绍Python C API中的列表、元组、字典的使用,详细的进行了API中方法的介绍。 Python List API List API 简单介绍 int PyList_Check(PyObject *p) 判断是否是一个Py...
    99+
    2023-01-31
    详解 Python API
  • Java使用ChatGPT的API详解
    目录介绍验证发出请求创建聊天PostMan实例介绍 OpenAI API 几乎可以应用于任何涉及理解或生成自然语言或代码的任务。我们提供一系列具有不同功率级别的模型,适用于不同的任务...
    99+
    2023-05-18
    Java使用ChatGPT的API Java ChatGPT的API
  • 一文详解C++中运算符的使用
    目录一、算术运算符二、关系运算符三、逻辑运算符四、位运算符五、赋值运算符六、杂项运算符一、算术运算符 运算符描述+把两个操作数相加-从第一个操作数中减去第二个操作数*把两个操作数相乘...
    99+
    2024-04-02
  • ResizeObserver API使用示例详解
    目录API介绍浏览器兼容性用法总结API介绍 当我们需要知道一个元素的大小变化或者屏幕横竖屏时,我们需要监听window.resize事件或者window.orientationch...
    99+
    2024-04-02
  • python中API调用的详解与示例
    本篇文章给大家带来了关于python的相关知识,其中主要介绍了关于API调用的相关问题,包括了API的调用和数据接口的调用、请求方法、几种常见API调用实例等等内容,下面一起来看一下,希望对大家有帮助。在日常工作中,可能需要结合网上现在的一...
    99+
    2022-06-16
    python
  • python如何实现API的调用详解
    目录前言API数据接口API的调用和数据接口的调用调用的基础-请求方法几种常见API调用实例百度AI相关API百度地图API有道APIuuidsign常用API分享总结前言 在日常工...
    99+
    2024-04-02
  • c# dynamic的使用详解
    目录类型转换方法中含有dynamic类型参数的重载问题dynamic可以简化反射。dynamic是FrameWork4.0的新特性。dynamic的出现让C#具有了弱语言类型的特性。...
    99+
    2024-04-02
  • C# RabbitMQ的使用详解
    目录安装编写消息接收端编写发送端测试发送端和接收端Fanout 模式Direct模式和RouteKeyTopic 模式本文目的如题。 安装 先说一下RabbitMQ的安装,建议使用D...
    99+
    2024-04-02
  • 一文带你了解ChatGPT API的使用
    目录1.概述2.内容2.1 ChatGPT优点2.2 ChatGPT的应用场景2.3 ChatGPT的发展前景3.API应用4.API代码实现4.1 Python...
    99+
    2023-02-27
    ChatGPT API使用 ChatGPT API
  • Java API文档的使用方法详解
    目录前言1. 概念2. 使用总结前言 学会使用 API 文档是一个开发者基本的素养,而许多初学者并不会在意 API 文档的使用,甚至从来没有接触过,所以写下这篇文章探讨 API 文档...
    99+
    2023-02-01
    java api文档使用方法 java的api文档 java api接口文档
  • React18 中的 Suspense API使用实例详解
    目录什么是新的 ReactJS Suspense API,什么时候应该使用它?什么是Suspense API?什么是 transition API最后什么是新的 ReactJS Su...
    99+
    2022-11-13
    React18 Suspense API React Suspense
  • 一文详解Python中哈希表的使用
    目录1. 前言2. 哈希表2.1 哈希函数2.2 哈希算法2.3 常见哈希算法2.4 哈希冲突3.总结1. 前言 哈希表或称为散列表,是一种常见的、使用频率非常高的数据存储方案。 哈...
    99+
    2024-04-02
  • 一文详解React组件API
    目录setState参数说明注意事项使用replaceState参数说明setProps参数说明replaceProps参数说明forceUpdate参数说明findDOMNodei...
    99+
    2023-05-17
    React组件API React组件 React API
  • C/C++ extern和static的使用详解
    目录前言externstaticc++ static members in class总结前言 在讲到extern和static的时候先了解一下定义和声明的基本概念 定义(defin...
    99+
    2024-04-02
  • 使用Python进行数独求解详解(一)
    目录1.引言2.描述数独九宫格3.寻找下一个空子单元格4.子单元格中设置值的合法性5.实现回溯算法6.性能表现7.总结1. 引言 本文为介绍流行的数独游戏的系列文章中的第一篇。更具体...
    99+
    2024-04-02
  • C/C++ 使用 MySQL API 操作 数据库 (API讲解 、案例分享)
    C/C++ 对 MySQL API 的使用 简介 文章目录 C/C++ 对 MySQL API 的使用简介1. C/C++ 使用 API介绍2. C/C++ 环境配置和操作示例代码2.1 My...
    99+
    2023-09-11
    mysql c++ visual studio
  • C++中的pair使用详解
    目录pair基本用法pair 其他使用重载pair的加减运算符在vector中使用pair是将2个数据组合成一组数据,当需要这样的需求时就可以使用pair,如stl中的map就是将k...
    99+
    2024-04-02
  • C++中gSOAP的使用详解
    目录SOAP简介gSOAP准备工作头文件构建客户端应用程序生成soap源码建立客户端项目构建服务端应用程序生成SOAP源码建立服务端项目打印报文SOAP测试项目源码总结本文主要介绍C...
    99+
    2024-04-02
  • 关于.NET6 Minimal API的使用方式详解
    目录前言使用方式几行代码构建Web程序更改监听地址日志操作基础环境配置主机相关设置默认容器替换中间件相关请求处理路由约束模型绑定绑定示例自定义绑定总结前言 随着.Net6的发布,微软...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作