我有如下代码:
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回调,则每次都会产生不同的值,对吗?(由于地址每次都不同。)
我有一个带有扩展部分的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.6和python2.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) 我试图找出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).
我怎样才能做到这一点?
我应该打电话的时候有点困惑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 API,我想创建一个包含类型对象的numpy数组Quaternion,这是我用C++编写的类.我已经有了这些数组(实际上是a std::vector),我想制作一个副本 - 或者如果可能的话使用相同的内存.
由于这不是基本类型,我需要使用Py_Object类型,不能使用PyArray_SimpleNew或类似的任何容易.
我猜我可能想要使用PyArray_NewFromDescr甚至PyArray_SimpleNewFromDescr,但我完全彻底迷失了如何创建PyArray_Descr我需要描述我的Quaternion类的对象.
谁能给我一些关于如何制作那个descr对象的指针?或者让我更好地了解如何构建我的numpy数组?
这基本上是这个问题的更一般版本,没有分心.
使用dastrobu的提示和我的SWIG包装器,我找到了一种方法.我知道不是每个人都在使用SWIG,但对于那些人,我对其他问题的回答显示了我是如何解决的.
我写了一个简单的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 扩展,我将用它来:
一种解决方案是在 Python 中实现“状态持有者”类。当我在 C 中调用初始化时,它返回我将存储在 Python 状态对象中的初始化数据。然后每次我需要执行步骤 (2) 时,我都会将其传递给 C 函数。但是,对于 Python 端和 C 端之间发生的所有数据穿梭/接口来说,这似乎非常低效。
如果可能的话,我想在 C 端使用状态对象来维护状态。来自 Python 端的初始化调用不会返回所有初始化数据,而仅返回一个 ID,以便在后续调用期间需要时可以引用 C 状态对象。
我将如何维护 C 端的状态?
我正在为 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) 我试图通过从 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) 有一个稀疏的 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)