C 扩展python,细节

2 篇文章 0 订阅

一.提取扩展函数的参数PyArg_ParseTuple()

int PyArg_ParseTuple(PyObject *arg, const char *format, ...);

参数 arg必须是一个元组对象,包含了Python传递给C函数的参数列表.

format 参数必须是一个字符串. format参数具体请查看:https://docs.python.org/zh-cn/3.7/c-api/arg.html#arg-parsing

剩余参数是各个变量的地址,类型要与格式字符串对应。

例子:

static PyObject *LG_add(PyObject * self, PyObject *args){
    int a,b;

    if (!PyArg_ParseTuple(args,"ii",&a,&b)) {    //将args 转为C int, 并放入 a,b 中.
          return NULL;
    }
    ...
}

 

int ok;
int i, j;
long k, l;
const char *s;
Py_ssize_t size;

ok = PyArg_ParseTuple(args, "s", &s); /* A string */
    /* Possible Python call: f('whoops!') */

ok = PyArg_ParseTuple(args, "lls", &k, &l, &s); /* Two longs and a string */
    /* Possible Python call: f(1, 2, 'three')*/

ok = PyArg_ParseTuple(args, "(ii)s#", &i, &j, &s, &size);
    /* A pair of ints and a string, whose size is also returned */
    /* Possible Python call: f((1, 2), 'three') */

{
    const char *file;
    const char *mode = "r";
    int bufsize = 0;
    ok = PyArg_ParseTuple(args, "s|si", &file, &mode, &bufsize);
    /* A string, and optionally another string and an integer */
    /* Possible Python calls:
       f('spam')
       f('spam', 'w')
       f('spam', 'wb', 100000) */
}

{
    int left, top, right, bottom, h, v;
    ok = PyArg_ParseTuple(args, "((ii)(ii))(ii)",
             &left, &top, &right, &bottom, &h, &v);
    /* A rectangle and a point */
    /* Possible Python call:
       f(((0, 0), (400, 300)), (10, 10)) */
}

{
    Py_complex c;
    ok = PyArg_ParseTuple(args, "D:myfunction", &c);
    /* a complex, also providing a function name for errors */
    /* Possible Python call: myfunction(1+2j) */
}

注意任何由调用者提供的Python对象引用是 借来的 引用;不要递减它们的引用计数!


二. 构造任意值 Py_BuildValue()

PyObject *Py_BuildValue(const char *format, ...);

接受一个格式字符串,与 PyArg_ParseTuple() 相同,但是参数必须是原变量的地址指针(输入给函数,而非输出).最终返回一个Python对象适合于返回C函数调用给Python代码。

例子, 左边是函数, 右边是输出.

Py_BuildValue("")                       None
Py_BuildValue("i", 123)                 123
Py_BuildValue("iii", 123, 456, 789)     (123, 456, 789)
Py_BuildValue("s", "hello")             'hello'
Py_BuildValue("y", "hello")             b'hello'
Py_BuildValue("ss", "hello", "world")   ('hello', 'world')
Py_BuildValue("s#", "hello", 4)         'hell'
Py_BuildValue("y#", "hello", 4)         b'hell'
Py_BuildValue("()")                     ()
Py_BuildValue("(i)", 123)               (123,)
Py_BuildValue("(ii)", 123, 456)         (123, 456)
Py_BuildValue("(i,i)", 123, 456)        (123, 456)
Py_BuildValue("[i,i]", 123, 456)        [123, 456]
Py_BuildValue("{s:i,s:i}",              "abc", 123, "def", 456)    {'abc': 123, 'def': 456}
Py_BuildValue("((ii)(ii)) (ii)",        (1, 2, 3, 4, 5, 6)          (((1, 2), (3, 4)), (5, 6))

三. 解析参数并构建值变量 也就是之前的format参数

s (str) [const char *]

将一个Unicode对象转换成一个指向字符串的C指针

3.2 数字

b (int) [unsigned char]

将一个非负的Python整型转化成一个无符号的微整型,存储在一个C unsigned char 类型中。

B (int) [unsigned char]

将一个Python整型转化成一个微整型并不检查溢出问题,存储在一个C unsigned char 类型中。

h (int) [short int]

将一个Python整型转化成一个C short int 短整型。

H (int) [unsigned short int]

将一个Python整型转化成一个C unsigned short int 无符号短整型,并不检查溢出问题。

i (int) [int]

将一个Python整型转化成一个C int 整型。

I (int) [unsigned int]

将一个Python整型转化成一个C unsigned int 无符号整型,并不检查溢出问题。

l (int) [long int]

将一个Python整型转化成一个C long int 长整型。

k (int) [unsigned long]

将一个Python整型转化成一个C unsigned long int 无符号长整型,并不检查溢出问题。

L (int) [long long]

将一个Python整型转化成一个C long long 长长整型。

K (int) [unsigned long long]

将一个Python整型转化成一个C unsigned long long 无符号长长整型,并不检查溢出问题。

n (int) [Py_ssize_t]

将一个Python整型转化成一个C Py_ssize_t Python元大小类型。

c (bytes 或者 bytearray 长度为1) [char]

将一个Python字节类型,如一个长度为1的 bytes 或者 bytearray 对象,转化成一个C char 字符类型。

在 3.3 版更改: 允许 bytearray 类型的对象。

C (str 长度为1) [int]

将一个Python字符,如一个长度为1的 str 字符串对象,转化成一个C int 整型类型。

f (float) [float]

将一个Python浮点数转化成一个C float 浮点数。

d (float) [double]

将一个Python浮点数转化成一个C double 双精度浮点数。

D (complex) [Py_complex]

将一个Python复数类型转化成一个C Py_complex Python复数类型。

3.3 其他对象

O (object) [PyObject *]

用一个C的对象指针存储一个Python对象(没有任何格式转换)。这样传递给C程序的是实际的对象。这个对象的引用计数不会增加。这个指针存储的不是 NULL

O! (object) [typeobject, PyObject *]

将一个Python对象存入一个C指针。和 O 类似,但是需要两个C参数:第一个是Python类型对象的地址,第二个是存储对象指针的C变量( PyObject* 变量)的地址。如果Python对象类型不对,会抛出 TypeError 异常。

O& (object) [converter, anything]

通过一个 converter 函数将一个Python对象转换成一个C变量。这需要两个参数:第一个是一个函数,第二个是一个C变量的地址(任意类型的),转化为 void * 类型。converter 函数像这样被调用:

status = converter(object, address);
p (bool) [int]

测试传入的值是否为真(一个布尔判断)并且将结果转化为相对应的C true/false整型值。如果表达式为真置``1``,假则置``0``。它接受任何合法的Python值。参见 逻辑值检测 获取更多关于Python如何测试值为真的信息。

(items) (tuple) [matching-items]

对象必须是Python序列,它的长度是 items 中格式单元的数量。C参数必须对应 items 中每一个独立的格式单元。序列中的格式单元可能有嵌套。

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值