标签: python-c-extension

PyArg_ParseTuple和一个回调函数指针

我有如下代码:

    PyObject *callback;
    PyObject *paths;

    // Process and convert arguments
    if (!PyArg_ParseTuple(args, "OO:schedule", &paths, &callback))
            return NULL;
Run Code Online (Sandbox Code Playgroud)

PyArg_ParseTuple内部到底发生了什么?我的猜测是,回调函数获取了我传递给args的函数指针(也是PyObject *)。PyArg_ParseTuple如何将函数指针转换为PyObject *?

我想知道的是,如果我两次传入相同的回调函数指针,将会发生什么。我认为回调在PyArg_ParseTuple内分配了一个新的PyObject,因此每次都会获得不同的内存地址,但是将包含相同的回调函数指针。

但是,如果我使用PyObject_Hash回调,则每次都会产生不同的值,对吗?(由于地址每次都不同。)

c python callback python-c-extension

5
推荐指数
1
解决办法
997
查看次数

Distutils找不到Python.h

我有一个带有扩展部分的distutils安装脚本,它看起来像这样:

from distutils.core import setup, Extension

my_module = Extension('my_module',
                sources = ['my_file.c', 'my_other_file.c'])

setup (name = 'my_module',
       version = '1.0',
       description = 'My module',
       ext_modules = [my_module])
Run Code Online (Sandbox Code Playgroud)

setup.py build在我的Mac上运行正常.当我移动到Debian机器时,它失败了:

error: Python/Python.h: No such file or directory
Run Code Online (Sandbox Code Playgroud)

python2.6python2.6-dev安装,并且该文件存在/usr/include/Python2.6.

它为问题文件执行的命令:

gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I/usr/include/python2.6 -c my_module.c -o -build/XYZ/my_module.o

所以它传递的是头文件的位置.

Mac与Linux环境之间唯一明显的区别是gcc-4.2 vs gcc-4.4和Python 2.7 vs Python 2.6

想法?

编辑:

在有问题的C文件中:

#include <Python/Python.h>
#include <Python/structmember.h>
Run Code Online (Sandbox Code Playgroud)

python gcc distutils python-c-extension

5
推荐指数
1
解决办法
1万
查看次数

使用pip时如何设置distutils使用的日志级别?

我试图找出error: Unable to find vcvarsall.bat之后的原因是什么pip install greenlet.我想设置distutils使用的日志级别,以便log.debug("Unable to find productdir in registry")打印调试消息.看了之后,def parse_command_line(self):我认为pip install --install-option="-vv" greenlet应该工作,但事实并非如此(冗长仍然是1).

我怎样才能做到这一点?

python logging distutils pip python-c-extension

5
推荐指数
1
解决办法
1491
查看次数

何时调用PyEval_InitThreads?

我应该打电话的时候有点困惑PyEval_InitThreads.一般来说,我知道PyEval_InitThreads只要使用非Python线程(即在扩展模块中生成的线程),就必须调用它.

但是,如果PyEval_InitThreads是嵌入Python解释器的C程序,或导入C扩展模块的Python程序,或者两者兼而有之,我很困惑.

因此,如果我编写一个内部启动线程的C扩展模块,PyEval_InitThreads在初始化模块时是否需要调用?

此外,PyEval_InitThreads 隐式获取全局解释器锁.因此,在调用之后PyEval_InitThreads,可能必须释放 GIL 或随后发生死锁.那么你如何释放锁?阅读文档后,PyEval_ReleaseLock()似乎是释放GIL的方法.但是,实际上,如果我在C扩展模块中使用以下代码:

   PyEval_InitThreads();
   PyEval_ReleaseLock();
Run Code Online (Sandbox Code Playgroud)

...然后在运行时Python中止:

Fatal Python error: drop_gil: GIL is not locked
Run Code Online (Sandbox Code Playgroud)

那么在获得GIL后如何释放GIL PyEval_InitThreads

c python python-c-api python-c-extension python-3.x

5
推荐指数
1
解决办法
1971
查看次数

使用C API创建numpy数组的自定义类对象

使用C API,我想创建一个包含类型对象的numpy数组Quaternion,这是我用C++编写的类.我已经有了这些数组(实际上是a std::vector),我想制作一个副本 - 或者如果可能的话使用相同的内存.

由于这不是基本类型,我需要使用Py_Object类型,不能使用PyArray_SimpleNew或类似的任何容易.

我猜我可能想要使用PyArray_NewFromDescr甚至PyArray_SimpleNewFromDescr,但我完全彻底迷失了如何创建PyArray_Descr我需要描述我的Quaternion类的对象.

谁能给我一些关于如何制作那个descr对象的指针?或者让我更好地了解如何构建我的numpy数组?

这基本上是这个问题的更一般版本,没有分心.

编辑:

使用dastrobu的提示和我的SWIG包装器,我找到了一种方法.我知道不是每个人都在使用SWIG,但对于那些人,我对其他问题的回答显示了我是如何解决的.

python numpy python-c-api python-c-extension

5
推荐指数
1
解决办法
981
查看次数

在python中导入时重定向C函数的stdout问题

我写了一个简单的C模块,使用printf打印到stdout.

// sample.c
func_print()
{
    printf("Hello World!\n");
}
Run Code Online (Sandbox Code Playgroud)

后来,我使用了这个包装器,SWIG所以我也可以func_print在我的python程序中使用它.在这个程序中,我已将stdout重定向到textctrl小部件.print正如预期的那样,我在textctrl小部件中正确打印的任何东西都能正确打印.

# sample.py
...
sys.stdout = textctrl          # textctrl is a TextCtrl widget (wxPython).
print 'Hello from Python!'     # prints in the textctrl widget, as expected.
Run Code Online (Sandbox Code Playgroud)

但是,当我调用C函数func_print()(来自sample.py)时,它会打印到终端而不是textctrl小部件.

func_print()                   # [Problem] prints to the terminal window, instead of the textctrl widget.  
Run Code Online (Sandbox Code Playgroud)

不知何故,似乎stdoutC模块中的for函数没有按预期重定向.请帮我解决这个问题.谢谢.

c python swig python-c-extension

4
推荐指数
1
解决办法
1108
查看次数

Python C 扩展 - 维护状态

我需要用 C 语言编写一个 Python 扩展,我将用它来:

  1. 对文件执行 CPU 密集型初始化;
  2. 进行多个函数调用,这些函数依赖于初始化的数据将结果返回给我;和
  3. 完成后释放内存

一种解决方案是在 Python 中实现“状态持有者”类。当我在 C 中调用初始化时,它返回我将存储在 Python 状态对象中的初始化数据。然后每次我需要执行步骤 (2) 时,我都会将其传递给 C 函数。但是,对于 Python 端和 C 端之间发生的所有数据穿梭/接口来说,这似乎非常低效。

如果可能的话,我想在 C 端使用状态对象来维护状态。来自 Python 端的初始化调用不会返回所有初始化数据,而仅返回一个 ID,以便在后续调用期间需要时可以引用 C 状态对象。

我将如何维护 C 端的状态?

python python-c-extension

4
推荐指数
1
解决办法
1213
查看次数

分段错误 - python C-extension中的核心转储

我正在为 python 编写一个 c 扩展。正如您在下面看到的,代码的目的是计算两个向量的欧几里德距离。第一个参数 n 是向量的维度,第二个,第三个参数是两个浮点列表。

我在 python 中调用函数是这样的:

import cutil
cutil.c_euclidean_dist(2,[1.0,1,0],[0,0])
Run Code Online (Sandbox Code Playgroud)

它运行良好,返回正确的结果。但是如果我这样做超过100次(尺寸为1 * 1000),则会导致分段错误-核心转储:

#!/usr/bin/env python
#coding:utf-8
import cutil
import science
import time
a = []
b = []
d = 0.0 
for x in range(2500):
    a.append([float(i+x) for i in range(1000)])
    b.append([float(i-x) for i in range(1000)])

t1 = time.time()
for x in range(500):
    d += cutil.c_euclidean_dist(1000,a[x],b[x])
print time.time() - t1
print d
Run Code Online (Sandbox Code Playgroud)

C代码在这里:

#include <python2.7/Python.h>
#include <math.h>

static PyObject* cutil_euclidean_dist(PyObject* self, PyObject* args) {
    PyObject *seq_a, *seq_b;
    int …
Run Code Online (Sandbox Code Playgroud)

c python linux python-c-extension

4
推荐指数
1
解决办法
6663
查看次数

如何从 C 的 PyObject 类型的函数将值从 C 返回到 python?

我试图通过从 python 调用 C 文件来传递一个值,然后再次将该值从 C 返回到 python。

我的问题是如何做到这一点?可以使用返回Py_BuildValue(a+b)类型的东西吗?

#include <Python.h>

static PyObject *
hello_world(PyObject *self, PyObject *noargs)
{
   int a=5,b=10;

   return Py_BuildValue(a+b); //This is Errorus.
}


static PyMethodDef
module_functions[] = {
    { "hello_world", hello_world, METH_NOARGS, "hello world method" },
    { NULL }
};



PyMODINIT_FUNC
inittesty2(void)
{
    Py_InitModule("testy2", module_functions);
}
Run Code Online (Sandbox Code Playgroud)

c python python-c-api python-c-extension python-extensions

4
推荐指数
1
解决办法
2164
查看次数

如何将特定的C模块移植到Python 3?

有一个稀疏的 pip包,目前只能用Python2编译.

当我安装它sudo pip install thinning然后尝试import thinning,我收到一个错误:

ImportError: /usr/lib/python3.5/site-packages/thinning.cpython-35m-x86_64-linux-gnu.so: undefined symbol: Py_InitModule3
Run Code Online (Sandbox Code Playgroud)

我认为这是因为Py_InitModule3Python3不再使用它了.这是完整的c源文件:

#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION

#include "Python.h"
#include "arrayobject.h"
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
#include <limits.h>

static PyObject *guo_hall_thinning(PyObject *self, PyObject *args);
int _guo_hall_thinning(unsigned char* binary_image, int width, int height);
void initthinning(void);

/* ==== Set up the methods table ====================== */
static PyMethodDef thinningMethods[] = {
    {"guo_hall_thinning",guo_hall_thinning, METH_VARARGS,
    "Takes a 2D numpy UBYTE array in C-order and thins it …
Run Code Online (Sandbox Code Playgroud)

python opencv numpy python-c-extension python-3.x

4
推荐指数
1
解决办法
750
查看次数