标签: python-c-extension

Python C API:打开PyObject类型

我有一些代码可以将Python与C++接口,但是每次看到它我都认为必须有更好的方法.在C++方面,有一个'variant'类型可以处理固定范围的基本类型 - int,real,string,variant变量等.我有一些代码使用Python API从等效的Python类型转换.它看起来像这样:

variant makeVariant(PyObject* value)
{  
  if (PyString_Check(value)) {
    return PyString_AsString(value);
  }
  else if (value == Py_None) {
    return variant();
  }
  else if (PyBool_Check(value)) {
    return value == Py_True;
  }
  else if (PyInt_Check(value)) {
    return PyInt_AsLong(value);
  }
  else if (PyFloat_Check(value)) {
    return PyFloat_AsDouble(value);
  }
  // ... etc
Run Code Online (Sandbox Code Playgroud)

问题是链式if-else ifs.它似乎是在调用switch语句,或者由类型标识符键入的创建函数的表或映射.换句话说,我希望能够写出如下内容:

  return createFunMap[typeID(value)](value);
Run Code Online (Sandbox Code Playgroud)

基于API文档的略读,直接获取'typeID'的最佳方法并不明显.我知道我可以这样做:

  PyTypeObject* type = value->ob_type;
Run Code Online (Sandbox Code Playgroud)

这显然让我快速了解类型信息,但是使用它与我感兴趣的有限类型集相关的最简洁方法是什么?

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

7
推荐指数
1
解决办法
4577
查看次数

我怎样才能从Python C代码断言?

我正在用C编写一个Python类,我想在我的调试代码中加入断言.assert.h很适合我.这只会被放入调试编译中,因此不会出现影响Python代码*用户的断言失败的可能性.

我试图划分我的'库'代码(它应该与链接到Python的代码分开),所以我可以从其他C代码中使用它.因此,我的Python方法是我的纯C代码的薄包装.

所以我不能在我的'库'代码中执行此操作:

if (black == white)
{
    PyErr_SetString(PyExc_RuntimeError, "Remap failed");
}
Run Code Online (Sandbox Code Playgroud)

因为这会用Python污染我的纯C代码.它也比简单的更丑陋

assert(black != white);
Run Code Online (Sandbox Code Playgroud)

我相信Distutils编译器总是设置NDEBUG,这意味着我assert.h甚至不能在调试版本中使用.

Mac OS和Linux.

救命!

*我听过一个论点反对在Python中调用C代码断言.

c python distutils python-c-api python-c-extension

7
推荐指数
1
解决办法
1221
查看次数

PyList_SetItem与PyList_SETITEM

据我所知,PyList_SetItem和PyList_SETITEM之间的区别在于PyList_SetItem将降低它覆盖的列表项的引用计数,而PyList_SETITEM则不会.

我有什么理由不能一直使用PyList_SetItem吗?或者如果我使用PyList_SetItem来初始化列表中的索引位置,我会遇到麻烦吗?

python python-c-extension

7
推荐指数
1
解决办法
1561
查看次数

如何在Cython中的新式缓冲区对象中包装C指针和长度?

我在Cython中编写了一个Python 2.7扩展模块. 如何创建一个实现新式缓冲区接口的Python对象,该接口包含C库提供给我的大块内存? 内存块只是一串字节,而不是结构或多维数组.我给了一个const void *指针和一个长度,以及一些指针保持有效的细节.

我无法复制内存 - 这会破坏我的应用程序的性能.

使用我可以简单使用的旧式缓冲区对象PyBuffer_FromMemory(),但我似乎无法找到一种类似的简单方法来生成新式缓冲区对象.

我是否必须创建自己的实现缓冲区接口的类?或者Cython提供了一种简单的方法吗?

我已经阅读了Cython文档中的Unicode和Passing StringsTyped Memoryviews页面,但文档不精确且不够完整,并且没有类似于我想要做的示例.

这是我尝试过的(test.pyx):

from libc.stdlib cimport malloc
from libc.string cimport memcpy

## pretend that this function is in some C library and that it does
## something interesting.  (this function is unrelated to the problem
## I'm experiencing -- this is just an example function that returns a
## chunk of memory that I want to wrap in …
Run Code Online (Sandbox Code Playgroud)

python cython python-c-extension python-2.7 memoryview

7
推荐指数
2
解决办法
2097
查看次数

Python C-API 模块退出处理程序 - 相当于 atexit?

我正在使用 Python 版本 2.6.4

当我的扩展模块退出/卸载时,我必须从 C 库调用一个函数。对于 C 扩展模块来说,atexit 的等效项是什么?

python python-c-api python-c-extension

6
推荐指数
1
解决办法
1586
查看次数

是否有NumPy C API函数将重置布局标志?

我手动修改NumPy数组的形状和步幅,这些数组可能(或可能不)使连续性标志无效.

  1. 我是否必须手动检查步幅是否与您期望的形状和NPY_C_CONTIGUOUS(或NPY_F_CONTIGUOUS)值相匹配?
  2. 是否有一个API函数可以为我执行此操作并自动清除或启用适当的标记?

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

6
推荐指数
1
解决办法
127
查看次数

ctypes.ArgumentError:不知道如何转换参数

我在 C 库中定义了一个函数,如下所示:

int* Test(char *str1,int id1,char *str2,float val,float *ls)
Run Code Online (Sandbox Code Playgroud)

我想在python中使用它,所以我编写了以下python代码:

str1 = 'a'
str2 = 'b'
id1 = 0
val = 1.0
system('g++ -c -fPIC libtraj.cpp -o test.o')
system('g++ -shared -Wl,-soname,test.so -o test.so test.o')
lib = cdll.LoadLibrary('./test.so')
num_item = 100000
ls = (ctypes.c_float * num_item)()
lib.Test.restype = ndpointer(dtype=ctypes.c_int, shape=(num_item,))
lib.Test.argtypes = [c_char_p]
a = create_string_buffer(str1)
b = create_string_buffer(str2)
ls_id = lib.Test(a,id1,b,val,ctypes.byref(ls))
Run Code Online (Sandbox Code Playgroud)

然后我运行这个python程序。我遇到错误说:

ls_id = lib.Test(a,id1,b,val,ctypes.byref(ls))
ctypes.ArgumentError: argument 4: <type 'exceptions.TypeError'>: Don't know how to convert parameter 4
Run Code Online (Sandbox Code Playgroud)

我的代码有什么问题?谢谢大家帮助我!!!

c python ctypes python-c-extension

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

从 C 代码调用 numpy 函数

我正在尝试将一些带有 Mex 扩展的 MatLab 代码移动到带有 numpy 和 scipy 库的 Python 中。使用这个精彩的教程http://www.scipy.org/Cookbook/C_Extensions/NumPy_arrays,我很快采用 C 函数从 Python 调用。但是一些 C 函数调用 MatLab 函数,所以我必须通过从 C 代码调用 numpy 和 scipy 函数来替换这段代码。

我试图做这样的事情Extending and Embedding the Python Interpreter。但是,我遇到了问题:如何将数组传递给函数参数。此外,在模块中查找函数然后为参数构建元组的这种漫长方式似乎并不优雅。

那么,例如,如何从 C 代码调用 numpy 模块中的 sum 函数?

我将不胜感激任何想法或链接。鲁本

PS这是一个例子:

    PyObject *feedback(PyObject *self, PyObject *args){
    PyArrayObject *Vecin;
    double mp=0,ret;
    if( !PyArg_ParseTuple(args,"O!d",&PyArray_Type,&Vecin,&mp)
      ||  Vecin == NULL ) return NULL;
    /* make python string with module name */
    PyObject *pName = PyString_FromString("numpy");
    if( pName == NULL){
        fprintf(stderr,"Couldn\'t setup …
Run Code Online (Sandbox Code Playgroud)

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

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

如何在可视化调试器中检查 python 对象?

在可视化调试器中调试 python 扩展时,检查器中 python 对象的原始解释对用户不友好。人们几乎看不到对象中的真实内容。有没有办法观察对象的python表示,比如vector<string>C++中的,它肯定是由visual studio转换为提供真实内容而不是低级实现的。

ps:以下是dict在python中的检查。 在此处输入图片说明

cpython python-c-api visual-studio python-c-extension python-2.7

5
推荐指数
0
解决办法
162
查看次数

从 C++ 扩展调用 python 类方法

我有一个名为 my_module 的 python 模块,在其中我有一个名为 my_class 的类,而 my_class 有一个名为 my_method 的类方法。

基于我在周围看到的其他示例,我提出了以下从 C++ 调用 my_method 的尝试,但目前所有这些尝试都返回 NULL(实际上是其中一个段错误......)

首先我导入模块和类:

PyObject* my_module_name = PyString_FromString((char*)"my_module");
PyObject* myModule = PyImport_Import(my_module_name);

PyObject* my_class = PyObject_GetAttrString(myModule2, (char*)"my_class");
if (!my_class) std::cout << "my_class failed " << std::endl;
Run Code Online (Sandbox Code Playgroud)

然后我构建用于作为元组传入的参数:

// These are the args
PyObject* my_args = PyTuple_Pack(
    5,
    PyString_FromString((char*)"first string"),
    PyString_FromString((char*)"next string"),
    PyFloat_FromDouble(0.0),
    PyFloat_FromDouble(1.0),
    Py_False
);
if (!my_args) std::cout << "my_args failed " << std::endl;
Run Code Online (Sandbox Code Playgroud)

然后我尝试调用实际方法

PyObject* my_method = PyObject_GetAttrString(my_class,(char*)"my_method");
if (!my_method) std::cout << "failed " << …
Run Code Online (Sandbox Code Playgroud)

c++ python python-c-api class-method python-c-extension

5
推荐指数
0
解决办法
1315
查看次数