Python和C对接的类型
在描述python接口的时候,我们谈到了python有着一套c特定的接口,而这个接口就是XXObject,由于C的参数数量固定,无法预设变量,参数类型确定等等,导致python和C语言对接需要一定的转换,需要提供更多的信息给C,才能使C/C++程序员能够在各个级别上对Python解释器的功能进行扩展。在使用C/C++对Python进行功能扩展之前和逆向,必须首先掌握Python解释所提供的C语言接口。
C语言正向开发py模块声明🚧
语言与语言之间,最难对接的莫过于类型,如果解决了类型的对接,就几乎解决了一半的问题
创建类型
首先就是基础类型,他们的特点是他们的类型是同一变量一致的(在这个变量中的所有内容类型相同)
基础类型
整数类型
PyObject* pInt = Py_BuildValue("i", 2003);
assert(PyInt_Check(pInt));
int i = PyInt_AsLong(pInt);
Py_DECREF(pInt);
浮点类型
PyObject* pFloat = Py_BuildValue("f", 3.14f);
assert(PyFloat_Check(pFloat));
float f = PyFloat_AsDouble(pFloat);
Py_DECREF(pFloat);
字符串类型
PyObject* pString = Py_BuildValue("s", "Python");
assert(PyString_Check(pString);
int nLen = PyString_Size(pString);
char* s = PyString_AsString(pString);
Py_DECREF(pString);
与他们不同的是元组和列表,他们其中的内容并不统一,类型多样,但是二者之间还是存在区别,元组不可扩展,列表可以进行扩展。
元组
PyObject* pTuple = PyTuple_New(3);
assert(PyTuple_Check(pTuple));
assert(PyTuple_Size(pTuple) == 3);
// 初始化元组
PyTuple_SetItem(pTuple, 0, Py_BuildValue("i", 2003));
PyTuple_SetItem(pTuple, 1, Py_BuildValue("f", 3.14f));
PyTuple_SetItem(pTuple, 2, Py_BuildValue("s", "Python"));
// 解析元组
int i;
float f;
char *s;
if (!PyArg_ParseTuple(pTuple, "ifs", &i, &f, &s))
PyErr_SetString(PyExc_TypeError, "invalid parameter");
// cleanup
Py_DECREF(pTuple);
列表
// 创建列表
PyObject* pList = PyList_New(3); // new reference
assert(PyList_Check(pList));
// pList[i] = i
for(int i = 0; i < 3; ++i)
PyList_SetItem(pList, i, Py_BuildValue("i", i));
// 插入元素
PyList_Insert(pList, 2, Py_BuildValue("s", "inserted"));
// 追加元素
PyList_Append(pList, Py_BuildValue("s", "appended"));
// 排序数组
PyList_Sort(pList);
// 反转数组
PyList_Reverse(pList);
// 数组切片
PyObject* pSlice = PyList_GetSlice(pList, 2, 4); // new reference
for(int j = 0; j < PyList_Size(pSlice); ++j) {
PyObject *pValue = PyList_GetItem(pList, j);
assert(pValue);
}
Py_DECREF(pSlice);
Py_DECREF(pList);
而字典则是最不同的,因为字典是固定的String类型+任意类型构成,并且其中涉及到了迭代器的内容,这里我们先不涉及那么多内容,只是先讲一下字典
字典
// 创建字典
PyObject* pDict = PyDict_New();
assert(PyDict_Check(pDict));
// pDict["first"] = 2003
PyDict_SetItemString(pDict, "first", Py_BuildValue("i", 2003));
// pDict["second"] = 3.14
PyDict_SetItemString(pDict, "second", Py_BuildValue("f", 3.14f));
// pDicts.Keys();
PyObject* pKeys = PyDict_Keys();
for(int i = 0; i < PyList_Size(pKeys); ++i) {
PyObject *pKey = PyList_GetItem(pKeys, i);
PyObject *pValue = PyDict_GetItem(pDict, pKey);
assert(pValue);
}
Py_DECREF(pKeys);
// 删除pDict["second"]
PyDict_DelItemString(pDict, "second");
Py_DECREF(pDict);
函数声明🚧
函数导出🚧
引用