python api讲解_Python C API的使用详解(一)

本文介绍了Python C API的使用,包括如何初始化和退出Python虚拟机,以及如何在C/C++中使用Python对象。通过Py_Initialize()、Py_Finalize()进行虚拟机管理,使用PyTypeObject、Py_BUILD_VALUE等宏进行数据类型转换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简介

介绍一下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.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

#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;

}

### 关于 UniApp 框架推荐资源与教程 #### 1. **Uniapp 官方文档** 官方文档是最权威的学习资料之一,涵盖了从基础概念到高级特性的全方位讲解。对于初学者来说,这是了解 UniApp 架构技术细节的最佳起点[^3]。 #### 2. **《Uniapp 从入门到精通:案例分析与最佳实践》** 该文章提供了系统的知识体系,帮助开发者掌握 Uniapp 的基础知识、实际应用以及开发过程中的最佳实践方法。它不仅适合新手快速上手,也能够为有经验的开发者提供深入的技术指导[^1]。 #### 3. **ThorUI-uniapp 开源项目教程** 这是一个专注于 UI 组件库设计实现的教学材料,基于 ThorUI 提供了一系列实用的功能模块。通过学习此开源项目的具体实现方式,可以更好地理解如何高效构建美观且一致的应用界面[^2]。 #### 4. **跨平台开发利器:UniApp 全面解析与实践指南** 这篇文章按照章节形式详细阐述了 UniApp 的各个方面,包括但不限于其工作原理、技术栈介绍、开发环境配置等内容,并附带丰富的实例演示来辅助说明理论知识点。 以下是几个重要的主题摘选: - **核心特性解析**:解释了跨端运行机制、底层架构组成及其主要功能特点。 - **开发实践指南**:给出了具体的页面编写样例代码,展示了不同设备间 API 调用的方法论。 - **性能优化建议**:针对启动时间缩短、图形绘制效率提升等方面提出了可行策略。 ```javascript // 示例代码片段展示条件编译语法 export default { methods: { showPlatform() { console.log(process.env.UNI_PLATFORM); // 输出当前平台名称 #ifdef APP-PLUS console.log('Running on App'); #endif #ifdef H5 console.log('Running on Web'); #endif } } } ``` #### 5. **其他补充资源** 除了上述提到的内容外,还有许多在线课程视频可供选择,比如 Bilibili 上的一些免费系列讲座;另外 GitHub GitCode 平台上也有不少优质的社区贡献作品值得借鉴研究。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值