开发者社区> 问答> 正文

编写扩展函数操作数组

你想编写一个C扩展函数来操作数组,可能是被array模块或类似Numpy库所创建。 不过,你想让你的函数更加通用,而不是针对某个特定的库所生成的数组。

展开
收起
哦哦喔 2020-04-17 18:11:08 2266 0
2 条回答
写回答
取消 提交回答
  • 有点尴尬唉 你要寻找的东西已经被吃掉啦!

    在C扩展模块中操作隐形指针:可以参考这篇文章: https://www.baidu.com/link?url=6djl4oF9q-bjXsKIc7n5xA5eoO3YbD_ISURCaytWx9o0B2dmmEhXclgxb_R

    2020-04-17 23:59:34
    赞同 展开评论 打赏
  • 为了能让接受和处理数组具有可移植性,你需要使用到 Buffer Protocol . 下面是一个手写的C扩展函数例子, 用来接受数组数据并调用本章开篇部分的 avg(double *buf, int len) 函数:
    
    /* Call double avg(double *, int) */
    static PyObject *py_avg(PyObject *self, PyObject *args) {
      PyObject *bufobj;
      Py_buffer view;
      double result;
      /* Get the passed Python object */
      if (!PyArg_ParseTuple(args, "O", &bufobj)) {
        return NULL;
      }
    
      /* Attempt to extract buffer information from it */
    
      if (PyObject_GetBuffer(bufobj, &view,
          PyBUF_ANY_CONTIGUOUS | PyBUF_FORMAT) == -1) {
        return NULL;
      }
    
      if (view.ndim != 1) {
        PyErr_SetString(PyExc_TypeError, "Expected a 1-dimensional array");
        PyBuffer_Release(&view);
        return NULL;
      }
    
      /* Check the type of items in the array */
      if (strcmp(view.format,"d") != 0) {
        PyErr_SetString(PyExc_TypeError, "Expected an array of doubles");
        PyBuffer_Release(&view);
        return NULL;
      }
    
      /* Pass the raw buffer and size to the C function */
      result = avg(view.buf, view.shape[0]);
    
      /* Indicate we're done working with the buffer */
      PyBuffer_Release(&view);
      return Py_BuildValue("d", result);
    }
    下面我们演示下这个扩展函数是如何工作的:
    
    >>> import array
    >>> avg(array.array('d',[1,2,3]))
    2.0
    >>> import numpy
    >>> avg(numpy.array([1.0,2.0,3.0]))
    2.0
    >>> avg([1,2,3])
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: 'list' does not support the buffer interface
    >>> avg(b'Hello')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: Expected an array of doubles
    >>> a = numpy.array([[1.,2.,3.],[4.,5.,6.]])
    >>> avg(a[:,2])
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ValueError: ndarray is not contiguous
    >>> sample.avg(a)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: Expected a 1-dimensional array
    >>> sample.avg(a[0])
    
    2.0
    >>>
    
    2020-04-17 18:11:16
    赞同 展开评论 打赏
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
动态、高效,蚂蚁动态卡片的内核逻辑 立即下载
JavaScript 语言在引擎级别的执行过程 立即下载
JS 语言在引擎级别的执行过程 立即下载