简介
本文章转载自 Mr. Lan的技术博客
介绍一下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;
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
编译方式及参数:
PyObject
Python的所有对象类型都是此类型的扩展。 这是一种类型,它包含Python将对象的指针视为对象所需的信息。 在正常的“发布”版本中,它仅包含对象的引用计数和指向相应类型对象的指针。 实际上没有任何东西被声明为PyObject,但是每个指向Python对象的指针都可以转换为PyObject *。 必须使用宏Py_REFCNT和Py_TYPE来访问成员。
宏描述,不包括全部
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。
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
- 82.
- 83.
- 84.
- 85.
- 86.
- 87.
- 88.
- 89.
- 90.
- 91.
- 92.
- 93.
- 94.
- 95.
- 96.
- 97.
- 98.
- 99.
创建整型的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);
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
创建长整型的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);
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
创建浮点类型的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);
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
创建布尔类型对象
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);
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
创建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);
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
创建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);
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
使用Py_None
Py_None
是一个全局的变量
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;
}