标签: python-c-api

将结构数组从Python传递给C.

[更新:问题解决了!见帖子的底部]

我需要允许python开发人员将打包数据数组(在本例中为顶点)传递给我的API,这是一系列通过Python C API手动公开的C++接口.我对此的初步印象是使用ctypes Structure类来允许这样的接口:

class Vertex(Structure):
_fields_ = [
    ('x', c_float),
    ('y', c_float),
    ('z', c_float),
    ('u', c_float),
    ('v', c_float),
    ('color', c_int)
] 

verts = (Vertex * 3)()
verts[0] = Vertex(0.0, 0.5, 0.0, 0.0, 0.5, 0xFF0000FF)
verts[1] = Vertex(0.5, -0.5, 0.0, 0.5, -0.5, 0x00FF00FF)
verts[2] = Vertex(-0.5, -0.5, 0.0, -0.5, -0.5, 0x0000FFFF)

device.ReadVertices(verts, 3) # This is the interfaces to the C++ object
Run Code Online (Sandbox Code Playgroud)

我试图传递的函数具有以下签名:

void Device::ReadVertices(Vertex* verts, int count);
Run Code Online (Sandbox Code Playgroud)

Python包装器看起来像这样:

static PyObject* Device_ReadVertices(Py_Device* self, PyObject* args)
{
    PyObject* py_verts;
    int …
Run Code Online (Sandbox Code Playgroud)

python structure python-c-api python-3.x

9
推荐指数
1
解决办法
3170
查看次数

在Python中,为什么用C语言实现的模块比纯Python模块更快,我怎么写一个?

python文档说,cPickle比Pickle更快的原因是,前者是用C实现的.这究竟是什么意思?

我正在使用Python制作高级数学模块,有些计算需要花费大量时间.这是否意味着如果我的程序在C中实现,它可以更快?

我想从其他Python程序导入这个模块,就像我可以导入cPickle一样.

你能解释一下如何在C中实现Python模块吗?

c python python-c-api

9
推荐指数
4
解决办法
3671
查看次数

自建扩展模块比内置c模块慢

要学习如何创建C扩展,我决定只复制一个内置.c文件(在本例中itertoolsmodule.c)并将其放在我的包中.我只能从更改的名称在模块内部itertoolsmypkg.

然后我编译它(Windows 10,MSVC Community 14)setuptools.Extension:

from setuptools import setup, Extension

itertools_module = Extension('mypkg.itertoolscopy',
                              sources=['src/itertoolsmodulecopy.c'])

setup(...
      ext_modules=[itertools_module])
Run Code Online (Sandbox Code Playgroud)

默认使用编译器标志/c /nologo /Ox /W3 /GL /DNDEBUG /MD,我在某处读取这些默认值等于python编译方式的设置.但是我使用conda(64位设置),所以这可能不一定是真的.

这一切都进展顺利 - 但是一个基准测试filterfalse显示它几乎比内置的慢2倍:

import mypkg
import itertools

import random

a = [random.random() for _ in range(500000)]
func = None

%timeit list(filter(func, a))
100 loops, best of 3: 3.42 ms per loop
%timeit list(itertools.filterfalse(func, a))
100 loops, best of 3: 3.41 ms …
Run Code Online (Sandbox Code Playgroud)

python performance python-c-api

9
推荐指数
1
解决办法
248
查看次数

numpy数组C api

我有一个C++函数返回一个std :: vector,我想在python中使用它,所以我使用的是C numpy api:

static PyObject *
py_integrate(PyObject *self, PyObject *args){
    ...
    std::vector<double> integral;
    cpp_function(integral);  // This changes integral
    npy_intp size = {integral.size()};
    PyObject *out = PyArray_SimpleNewFromData(1, &size, NPY_DOUBLE, &(integral[0]));
    return out;
}
Run Code Online (Sandbox Code Playgroud)

这是我从python中调用它的方式:

import matplotlib.pyplot as plt

a = py_integrate(parameters)
print a
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(a)
print a
Run Code Online (Sandbox Code Playgroud)

会发生什么:第一次打印没问题,值是正确的.但是当我描绘a他们不是; 在第二打印我看到这样很奇怪的值1E-308 1E-308 ...0 0 0 ...为未初始化的内存.我不明白为什么第一次打印没问题.

部分解决方案(不工作):

static void DeleteVector(void *ptr)
{
    std::cout << "Delete" << std::endl;
    vector * v …
Run Code Online (Sandbox Code Playgroud)

c python numpy vector python-c-api

8
推荐指数
1
解决办法
5676
查看次数

从C创建一个实现__dict__的Python类型?

  • 如何创建一个类型,以便__dict__在Python中定义一个"普通"类?
  • 有没有__dict__s 的非动态类型的例子?
  • 通过Python定义的类型是否PyTypeObject通过type_new

有一个tp_dict成员PyTypeObject,但我找不到有关它如何使用的信息.此外,还似乎有什么东西在事情typeobject.ctype_new,但我不能清楚地破译它.

以下是我发现的一些相关信息:

c python types python-c-api python-3.x

8
推荐指数
1
解决办法
2033
查看次数

如何从python引用C文件中的#defines?

我有一个C文件,有一堆#defines用于我想从python引用的位.有足够的它们,我宁愿不将它们复制到我的python代码中,而是有一种可接受的方法直接从python引用它们?

注意:我知道我可以打开头文件并解析它,这很简单,但如果有更多的pythonic方式,我想使用它.

编辑:

这些是非常简单的#define,用于定义掩码中位的含义,例如:

#define FOO_A 0x3
#define FOO_B 0x5
Run Code Online (Sandbox Code Playgroud)

python-c-api python-c-extension

8
推荐指数
2
解决办法
5716
查看次数

是否有完整的内置函数列表,无法使用关键字参数调用?

人们在答案a1,a2中提到了这一点

由于Python C级API的开发方式,许多内置函数和方法实际上没有参数的名称.

我发现它真的很烦人因为我无法通过查看文档来了解它.例如,eval

eval(表达式,globals = None,locals = None)

然后我写了这行代码

print(eval('a+b', globals={'a':1, 'b':2}))
Run Code Online (Sandbox Code Playgroud)

并得到了TypeError: eval() takes no keyword arguments.那么有这种功能的完整列表吗?如何知道函数是否允许包含关键字参数?

python arguments python-c-api

8
推荐指数
1
解决办法
358
查看次数

Python:从 C 模块生成函数存根

我使用 Python C API 用 C/C++ 创建了一个 Python 模块。我在 setup.py 中使用 setuptools.Extension 。

它创建一个 .py 文件,该文件从某些已编译的 .pyd 文件加载 python 模块:

def __bootstrap__():
    global __bootstrap__, __loader__, __file__
    import sys, pkg_resources, imp
    __file__ = pkg_resources.resource_filename(__name__, 'zroya.cp36-win32.pyd')
    __loader__ = None; del __bootstrap__, __loader__
    imp.load_dynamic(__name__,__file__)
__bootstrap__()
Run Code Online (Sandbox Code Playgroud)

但它不会为 IDE 自动完成功能生成 python 存根。我希望所有导出的函数和类都可以从 .py 文件中可见:

def myfunction_stub(*args, **kwargs):
    """
    ... function docstring
    """
    pass
Run Code Online (Sandbox Code Playgroud)

是否可以?或者我是否必须创建一些 python“预处理器”来从 .pyd 文件加载数据并生成带有文档字符串的存根?

源代码可在github上获取。

python-c-api python-3.x

8
推荐指数
1
解决办法
2680
查看次数

Python C API:如何检查对象是否是类型的实例

我想检查一个对象是否是某个类的实例。在 Python 中,我可以使用isinstance(obj, cls). 在 C/C++ 中,我发现了一个名为PyObject_IsInstance的函数。但它似乎不起作用isinstance

详细(也称为下面的示例代码):

  1. 在 C++ 中,我定义了我的自定义类型My。类型定义为MyType,对象定义为MyObject
  2. 添加MyType到名为 name 的导出模块My
  3. 在 Python 中,创建一个新实例my = My(),并isinstance(my, My)返回True
  4. 而在C++中,我们使用PyObject_IsInstance(my, (PyObject*)&MyType)检查my,并且返回0,这意味着my不是由定义的类的实例MyType

完整的C++代码:

#define PY_SSIZE_T_CLEAN
#include <python3.6/Python.h>
#include <python3.6/structmember.h>
#include <stddef.h>

typedef struct {
    PyObject_HEAD
    int num;
} MyObject;

static PyTypeObject MyType = []{
    PyTypeObject ret = {
        PyVarObject_HEAD_INIT(NULL, …
Run Code Online (Sandbox Code Playgroud)

c++ python python-c-api

8
推荐指数
1
解决办法
5006
查看次数

如何在 Python C API 中创建 Enum 对象?

我正在努力如何在 Python C API 中创建 python Enum 对象。enum 类已赋值tp_basePyEnum_Type,因此它继承了 Enum 。但是,我无法找到一种方法来告诉 Enum 基类枚举中有哪些项目。我想允许使用__members__每个 Python 枚举提供的属性从 Python 进行迭代和查找。

谢谢你,

耶勒

c python python-c-api

8
推荐指数
1
解决办法
808
查看次数