Windows10 C++(VS2017)调用python(python3.8)-2.基本数据类型转换(str,int,byte,float,tuple,dict,list,set) tcy

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 

#include 

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<实例3:
#include 
#include 
#include 

using namespace std;

//将C的基本数据类型转为python的基本类型(str,byte,int,float)
PyObject *CTypeTo_Py(void *value, const char *dtypes)
{
 map 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<
实例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

 

你可能感兴趣的:(C/C++)