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 <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <Python.h>
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 <iostream>
#include <Python.h>
#include <map>
#include <fstream>
using namespace std;
void print(PyObject *py_obj, const char *text = "")
{
const char *filename = "test.txt";
FILE *fp;
char buf[2048];
errno_t err=0;
//write data in file:
errno = fopen_s(&fp, filename, "w");
//rewind(fp);
PyObject_Print(py_obj, fp, Py_PRINT_RAW);
fclose(fp);
//read data from file:
err = fopen_s(&fp, filename, "r");
fgets(buf, 2048, fp);
cout << text << buf << endl<<endl;
fclose(fp);
}
int main()
{
Py_Initialize();
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./')");
PyObject *pValue = NULL;
//数据类型检验:
pValue = Py_BuildValue("s", "");
//输出的是python的数据类型str,byte,int,float,list,tuple,dict,set
cout << "datatype=" << pValue->ob_type->tp_name << endl;//str
pValue = Py_BuildValue("K", 123);
cout << "datatype=" << PyLong_Check(pValue) << endl;//1
//python数据测试:
str:
pValue = Py_BuildValue("C", 'T');
print(pValue, "1.1.str=");//T
pValue = Py_BuildValue("s", "hello");
print(pValue, "1.2.str=");//'hello'
pValue = Py_BuildValue("s#", "hello", 4);
print(pValue, "1.3.str=");// 'hell'
pValue = Py_BuildValue("ss", "hello", "world");
print(pValue, "1.4.str=");//('hello', 'world')
//byte:
pValue = Py_BuildValue("c", 'T');
print(pValue, "1.5.byte=");//b'T'
pValue = Py_BuildValue("y", "hello");
print(pValue, "1.6.byte=");// b'hello'
pValue = Py_BuildValue("y#", "hello", 4);
print(pValue, "1.7.byte=");// b'hello'
//int:
pValue = Py_BuildValue("i", 123); //123
print(pValue, "1.8.pValue=");
pValue = pValue = Py_BuildValue("iii", 123, 456, 789);
print(pValue, "1.9.pValue=");//(123, 456, 789)
//float/double:
pValue = pValue = Py_BuildValue("f", 3.14);
print(pValue, "1.a.float=");//3.14
pValue = pValue = Py_BuildValue("d", 6.28);
print(pValue, "1.b.double=");//6.28
//tuple:
pValue = Py_BuildValue("()");
print(pValue, "2.1.1.tuple=");// ()
pValue = Py_BuildValue("(i)", 123);
print(pValue, "2.1.2.tuple=");// (123,)
pValue = Py_BuildValue("(ii)", 123, 456);
print(pValue, "2.1.3.tuple=");// (123, 456)
pValue = Py_BuildValue("(i,i)", 123, 456);
print(pValue, "2.1.4.tuple=");// (123, 456)
pValue = Py_BuildValue("((ii)(ii)) (ii)", 1, 2, 3, 4, 5, 6);
print(pValue, "2.1.5.tuple=");// (((1, 2), (3, 4)), (5, 6))
//list:
pValue = Py_BuildValue("[i,i]", 123, 456);
print(pValue, "2.2.1.list=");// [123, 456]
//dict:
pValue = Py_BuildValue("{s,s}", "abc", "def");
print(pValue, "2.3.1.dict=");// {'abc', 'def'}
pValue = Py_BuildValue("{s:i,s:i}", "abc", 123, "def", 456);
print(pValue, "2.3.2.dict=");// {'abc': 123, 'def': 456}
//set:
PyObject *it = PyObject_GetIter(pValue);
PyObject* pset = PySet_New(it);
cout << "2.4.1.type="<<pset->ob_type->tp_name << endl;//set
pValue = Py_BuildValue("(i,i)", 123, 456);
//不能添加list,没有哈希属性:
PySet_Add(pset, pValue);
print(pset, "2.4.2.dict=");// {(123, 456), 'def', 'abc'}
Py_Finalize();
return 0;
}
实例3:
#include <iostream>
#include <Python.h>
#include <map>
using namespace std;
//将C的基本数据类型转为python的基本类型(str,byte,int,float)
PyObject *CTypeTo_Py(void *value, const char *dtypes)
{
map<const char*, const char*> dict = {
{ "bool" ,"bool"},
{ "byte" ,"c"},
{ "char" ,"b"},
{ "unsigned char" ,"B"},
{ "char *" ,"s"},
{ "str" ,"s"},
{ "int" ,"i"},
{ "unsigned" ,"I"},
{ "unsigned int" ,"I"},
{ "short" ,"h"},
{ "short int" ,"h"},
{ "unsigned short" ,"H"},
{ "unsigned short int" ,"H"},
{ "long" ,"l"},
{ "long int" ,"l"},
{ "unsigned long" ,"k"},
{ "unsigned long int" ,"k"},
{ "long long" ,"L"},
{ "long long int" ,"L"},
{ "unsigned long long" ,"K"},
{ "unsigned long long int" ,"K"},
{ "size_t" ,"n"},
{ "float" ,"f"},
{ "double" ,"d"}
};
PyObject *result=NULL;
if (dtypes == "bool")
result = Py_BuildValue(dict[dtypes], *(bool*)value);
else if (dtypes == "byte")
result = Py_BuildValue(dict[dtypes], *(char*)value);
else if (dtypes == "char")
result = Py_BuildValue(dict[dtypes], *(char*)value);
else if (dtypes == "unsigned char")
result = Py_BuildValue(dict[dtypes], *(unsigned char*)value);
else if (dtypes == "char *" || dtypes == "str")
{
const char *p;
p = (char *)value;
result = Py_BuildValue(dict[dtypes], p);
}
else if (dtypes == "int")
result = Py_BuildValue(dict[dtypes], *(int*)value);
else if (dtypes == "unsigned" || dtypes == "unsigned int")
result = Py_BuildValue(dict[dtypes], *(unsigned*)value);
else if (dtypes == "short" || dtypes == "short int")
result = Py_BuildValue(dict[dtypes], *(short*)value);
else if (dtypes == "unsigned short" || dtypes == "unsigned short int")
result = Py_BuildValue(dict[dtypes], *(unsigned short*)value);
else if (dtypes == "long" || dtypes == "long int")
result = Py_BuildValue(dict[dtypes], *(long*)value);
else if (dtypes == "unsigned long" || dtypes == "unsigned long int")
result = Py_BuildValue(dict[dtypes], *(unsigned long*)value);
else if (dtypes == "long long" || dtypes == "long long int")
result = Py_BuildValue(dict[dtypes], *(long long*)value);
else if (dtypes == "unsigned long long" || dtypes == "unsigned long long int")
result = Py_BuildValue(dict[dtypes], *(unsigned long long*)value);
else if (dtypes == "size_t")
result = Py_BuildValue(dict[dtypes], *(size_t*)value);
else if (dtypes == "float")
result = Py_BuildValue(dict[dtypes], *(float*)value);
else if (dtypes == "double")
result = Py_BuildValue(dict[dtypes], *(double*)value);
return result;
}
int main()
{
Py_Initialize();
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./')");
PyObject *pValue = NULL;
int x1 = 100;
pValue = CTypeTo_Py((int *)&x1, "int");
int x2 = _PyLong_AsInt(pValue);
cout << "x2=" << x2<<endl;
const char *text1 = "This is a book.";
pValue = CTypeTo_Py((char *)text1, "str");
const char *text2 = PyUnicode_AsUTF8(pValue); // 转成C的字符指针
printf("text2 = %s\n", text2);
Py_Finalize();
return 0;
}
实例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<double> 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