1. 程式人生 > >Python C AP的使用詳解(一)

Python C AP的使用詳解(一)

nds 項目 namespace 以及 int float 數據大小 mem else

簡介

介紹一下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;
}

編譯方式及參數:

下面是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 <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;
}

Python C AP的使用詳解(一)