Python C AP的使用詳解(一)
阿新 • • 發佈:2018-09-01
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的使用詳解(一)