1.概念:
1.1.PyObject类型
Python所有对象类型都是此类型扩展。它包含Python将对象的指针视为对象所需的信息。
在正常“发布”版本中,它仅包含对象的引用计数和指向相应类型对象的指针。
每个指向Python对象的指针都可转为PyObject *,必须使用宏Py_REFCNT和Py_TYPE来访问成员。
宏描述:
Py_TYPE: 获取Python对象的数据类型
Py_REFCNT: Python的引用计数器
Py_SIZE: 获取Python数据大小
1.2.Py_BuildValue
用途:
将C所有基本数据类型转换成Python可访问的数据类型
标识符介绍:
s(str或None)[char *] or z or U
将C字符串(null结尾)转换为Python str(utf-8编码)或None(char *p=NULL)
s#(str或None)[char *,int] or z or U
将C字符串及长度(null结尾)转换为Python str(utf-8编码)或None(char *p=NULL忽略长度)
y(字节)[char *]
将C字符串转Python字节或None(char *p=NULL)
y#(字节)[char *,int]
将C字符串及长度转Python字节或None(char *p=NULL忽略长度)
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
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 *] or S
不改变Python对象的传递(引用计数除外,它增加1)。如传入对象是NULL指针,
则假定这是因为产生参数的调用发现错误并设置了异常。
因此,Py_BuildValue()将返回NULL但不会引发异常。如尚未引发异常,则设置SystemError。
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
2.创建Python对象
2.1.创建整型的Python对象
// 使用Py_BuildValue创建整型对象:
void int_object()
{
// 第一种方式
PyObject *py_ival1 = Py_BuildValue("i", -5987); // Python有符号整型
PyObject *py_ival2 = PyLong_FromLong(-8979);
int ival1 = PyLong_AsLong(py_ival); // 把Python有字符整型转换成C的有字符整型
int ival2 = PyLong_AsLong(py_ival2); // 把Python有字符整型转换成C的有字符整型
printf("ival1 = %d, ival2 = %d\n", ival1, ival2);
// 第二种方式
PyObject *py_uval1 = Py_BuildValue("I", 465486); // Python无符号整型
PyObject *py_uval2 = PyLong_FromUnsignedLong(1654864);
unsigned int uval1 = PyLong_AsUnsignedLong(py_uval1); // 把Python无字符整型转换成C的无字符整型
unsigned int uval2 = PyLong_AsUnsignedLong(py_uval2); // 把Python无字符整型转换成C的无字符整型
printf("uval1 = %u, uval2 = %u\n", uval1, uval2);
}
2.2. 创建长整型的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);
}
2.3.创建浮点类型的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);
}
2.4.创建布尔类型对象
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);
}
2.5.创建Python string对象
void string_object()
{
// 第一种方式
const char *pstr = "this is a test";
PyObject *py_str = Py_BuildValue("s", pstr); // Python 字符串对象
const char *c_pstr = PyUnicode_AsUTF8(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 = "Tom";
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);
}
2.6.使用Py_None
//Py_None是一个全局的变量
PyObject* none_object()
{
Py_RETURN_NONE; // 不需要自己return
}
3.实例1:
#include
#include
#include
#include
int main()
{
Py_Initialize();// 初始化Python虚拟机
// 判断Python虚拟机是否成功
if (Py_IsInitialized() == 0){printf("fal to initialize Python\n");return -1;}
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./')");
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");}
Py_Finalize();// 退出Python虚拟机
return 0;
}
实例2:
#include
#include
#include
实例3:
#include
#include
#include
实例4:
//PyObject * Py_None//Python None对象
//Py_RETURN_NONE//python返回None 相当于return None
PyObject *cBoolToPyBool(bool value) { return Py_BuildValue("b", value); }
PyObject *cUIntToPyBytes(unsigned int value) { return Py_BuildValue("result", value); }
PyObject *cCharToPyInt(char value) { return Py_BuildValue("b", value); }
PyObject *cUCharToPyInt(unsigned char value) { return Py_BuildValue("B", value); }
PyObject *cIntToPyInt(int value) { return Py_BuildValue("i", value); }
PyObject *cShortToPyInt(short value) { return Py_BuildValue("h", value); }
PyObject *cLongToPyInt(long value) { return Py_BuildValue("l", value); }
PyObject *cLongLongToPyInt(long long value) { return Py_BuildValue("L", value); }
PyObject *cUIntToPyInt(unsigned int value) { return Py_BuildValue("I", value); }
PyObject *cUShortToPyInt(unsigned short value) { return Py_BuildValue("H", value); }
PyObject *cULongToPyInt(unsigned long value) { return Py_BuildValue("k", value); }
PyObject *cULongLongToPyInt(unsigned long long value) { return Py_BuildValue("K", value); }
PyObject *cSSize_tToPyInt(long long value) { return Py_BuildValue("n", value); }
PyObject *cFloatToPyFloat(float value) { return Py_BuildValue("f", value); }
PyObject *cDoubleToPyFloat(double value) { return Py_BuildValue("d", value); }
PyObject *cComplexToPyComplex(complex value) { return Py_BuildValue("D", value); }
PyObject *cRefAdd(PyObject *value) { return Py_BuildValue("O", value); }//不变Python对象传递;引用计数加1
PyObject *cRef(PyObject * value) { return Py_BuildValue("N", value); } //不变Python对象传递;不增加对象引用计数;用做构造函数参数
//void *:
void* pyIntToVoid_p(PyObject *value) { return PyLong_AsVoidPtr(value); }//将Python整数pylong转换为C void指针
long pyIntToCLong(PyObject *value) { return PyLong_AsLong(value); }
long pyIntToCLongOverflow(PyObject *value, int * overflow) { return PyLong_AsLongAndOverflow(value, overflow); }//溢出判断-1
size_t pyIntToSize_t(PyObject *value) { return PyLong_AsSize_t(value); } //返回-1错误
unsigned long pyIntToULong(PyObject *value) { return PyLong_AsUnsignedLong(value); }
long long pyIntToCLongLong(PyObject *value) { return PyLong_AsLongLong(value); }
long long pyIntToCLongLongOverflow(PyObject *value, int * overflow) { return PyLong_AsLongLongAndOverflow(value, overflow); } //溢出判断
unsigned long long pyIntToCULongLong(PyObject *value) { return PyLong_AsUnsignedLongLong(value); }
double pyFloatToDouble(PyObject *value) { return PyLong_AsDouble(value); }
//string:
PyObject *cCharToPyStr(const char *value){return Py_BuildValue("s", value);} //如果C字符串指针为NULL,则表示None
PyObject *cCharToPyBytes(char *value){ return Py_BuildValue("y", value);} //如果C字符串指针为NULL,则返回None
const char *pyStrToCStr(PyObject *value) { return PyUnicode_AsUTF8(value); }
PyObject *cWcharToStr(const wchar_t *wstr, Py_ssize_t n) { return PyUnicode_FromWideChar(wstr, n); }//宽字符
const wchar_t *pyStrToCWchar(PyObject *value, Py_ssize_t *n) { return PyUnicode_AsWideCharString(value, n); }//宽字符
=========================================================================================
测试:
void test_str()
{
const char *str1 = "Tom";
PyObject *pystr1 = cCharToPyStr(str1);
const char *str2 = pyStrToCStr(pystr1);
printf("1.1.str2 = %s\n", str2);//Tom
const wchar_t *wstr1 = L"Bob";
size_t n = wcsnlen_s(wstr1, 256);
cout <<"1.2.wstr1.n="<< n << endl;//3
PyObject *pywchar = cWcharToStr(wstr1, 4);
Py_ssize_t n1 = 4;
const wchar_t *wstr2 = pyStrToCWchar(pywchar, &n1);
wcout << "1.3.wstr2=" << wstr2 << endl;//Bob
}
int main()
{
Py_Initialize();
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./')");
//**********************
test_str();
//**********************
Py_Finalize();
return 0;
}
=============================================================================
https://blog.51cto.com/11293981/2167897?source=drh
https://blog.csdn.net/ziweipolaris/article/details/83689597