ctypes 学习

ctypes

Python解释器只可以直接调用C的函数接口,而对于C++的函数接口,
则需要通过extern声明转换为C的函数接口,而后才能进行dll编译,以供Python调用。

指定返回类型 self.py_lastrans.pylas_local_mecator.restype= c_int
传递字符串 dest_las = dest_las.encode()
5个0的整形数组:(c_int * 5)()
(c_int * 4) * 3 这样即得到了一个4 * 3的二维int类型数组的类
((c_int * 4) * 3)() 这样就得到了一个所有值均为0的二维数组对象



PyObject
https://www.jb51.net/article/64094.htm
https://www.zhihu.com/question/55014214

在Python的C语言扩展接口中,大部分函数都有一个或者多个参数为PyObject指针类型,
并且返回值也大都为PyObject指针。
在C/C++中处理Python对象时,对引用计数进行正确的维护是一个关键问题,处理不好将很容易产生内存泄漏。
Python的C语言接口提供了一些宏来对引用计数进行维护,最常见的是用Py_INCREF()来增加
使Python对象的引用计数增1,用Py_DECREF()来使Python对象的引用计数减1。

Python定义了六种数据类型:整型、浮点型、字符串、元组、列表和字典,在使用C语言对Python进行功能扩展时,首先要了解如何在C和Python的数据类型间进行转化。

整型、浮点型和字符串
// build an integer
PyObject* pInt = Py_BuildValue("i", 2003);
assert(PyInt_Check(pInt));
int i = PyInt_AsLong(pInt);
Py_DECREF(pInt);
// build a float
PyObject* pFloat = Py_BuildValue("f", 3.14f);
assert(PyFloat_Check(pFloat));
float f = PyFloat_AsDouble(pFloat);
Py_DECREF(pFloat);
// build a string
PyObject* pString = Py_BuildValue("s", "Python");
assert(PyString_Check(pString);
int nLen = PyString_Size(pString);
char* s = PyString_AsString(pString);
Py_DECREF(pString);
元组
// create the tuple
PyObject* pTuple = PyTuple_New(3);
assert(PyTuple_Check(pTuple));
assert(PyTuple_Size(pTuple) == 3);
// set the item
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"));
// parse tuple items
int i;
float f;
char *s;
if (!PyArg_ParseTuple(pTuple, "ifs", &i, &f, &s))
  PyErr_SetString(PyExc_TypeError, "invalid parameter");
// cleanup
Py_DECREF(pTuple);
列表
// create the list
PyObject* pList = PyList_New(3); // new reference
assert(PyList_Check(pList));
// set some initial values
for(int i = 0; i < 3; ++i)
  PyList_SetItem(pList, i, Py_BuildValue("i", i));
// insert an item
PyList_Insert(pList, 2, Py_BuildValue("s", "inserted"));
// append an item
PyList_Append(pList, Py_BuildValue("s", "appended"));
// sort the list
PyList_Sort(pList);
// reverse the list
PyList_Reverse(pList);
// fetch and manipulate a list slice
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);
// cleanup
Py_DECREF(pList);
字典
// create the dictionary
PyObject* pDict = PyDict_New(); // new reference
assert(PyDict_Check(pDict));
// add a few named values
PyDict_SetItemString(pDict, "first", 
           Py_BuildValue("i", 2003));
PyDict_SetItemString(pDict, "second", 
           Py_BuildValue("f", 3.14f));
// enumerate all named values
PyObject* pKeys = PyDict_Keys(); // new reference
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);
// remove a named value
PyDict_DelItemString(pDict, "second");
// cleanup
Py_DECREF(pDict);

模块封装

int fact(int n)
{
 if (n <= 1) 
  return 1;
 else 
  return n * fact(n - 1);
}

#include 
导出函数
PyObject* wrap_fact(PyObject* self, PyObject* args) 
{
 int n, result;
 
 if (! PyArg_ParseTuple(args, "i:fact", &n))
  return NULL;
 result = fact(n);
 return Py_BuildValue("i", result);
}
方法列表
static PyMethodDef exampleMethods[] = 
{
 {"fact", wrap_fact, METH_VARARGS, "Caculate N!"},
 {NULL, NULL}
};
初始化函数
void initexample() 
{
 PyObject* m;
 m = Py_InitModule("example", exampleMethods);
}

你可能感兴趣的:(ctypes 学习)