标签: python-c-api

在Python C API中,为什么包装函数是静态的

所以我有下面用C扩展python的示例代码

#include <python.h>

static PyObject* sayhello(PyObject* self, PyObject *args) {
   const char* name;

   if (!PyArg_ParseTuple(arg, "s", &name))
       return NULL;

    printf("Hello %s !\n", name);

    Py_RETURN_NONE;
}

static PyMethodDef HelloMethods[] = 
{
    {"say_hello", say_hello, METH_VARARGS, "Greet Somebody."},
    {NULL, NULL, 0, NULL}
};

PyMODINIT_FUNC inithello(void) {
    (void) Py_InitModule("hello", HelloMethods);
}
Run Code Online (Sandbox Code Playgroud)

而我的问题是为什么下面的包装函数静态

   static PyObject* sayhello(PyObject* self, PyObject *args) {
Run Code Online (Sandbox Code Playgroud)

c python python-c-api

2
推荐指数
1
解决办法
233
查看次数

当文件有导入语句时,Python C api PyImport_importmodule 失败

我尝试使用Python C api在C++中调用Python中的函数,测试成功。

但是,如果我打算导入一个已经导入其他模块的模块,那么 Pymodule_findmodule 将返回 Null,即使它在那里并创建了一个编译文件。这是我的代码

Py_Initialize();
PySys_SetPath("C:/Users/Mik/Documents/GitHub/youtube-dl");      
PyObject * pythonFile = PyImport_ImportModule("test2");
Run Code Online (Sandbox Code Playgroud)

这是该目录中名为 test2.py 的 python 文件,其中包含一个名为 test_dl.py 的文件和一个名为 TESTDL 的类

from test_dl import TESTDL 
def someFunction(someInput):
    return 12345
Run Code Online (Sandbox Code Playgroud)

一旦我添加了导入行,我的程序就不再将其识别为模块

编辑:结果 test_dl 的第一行为:

 from __future__ import unicode_literals
Run Code Online (Sandbox Code Playgroud)

这就是我收到此 ImportError: No module named future的原因

谢谢!

c++ python python-c-api python-import

2
推荐指数
1
解决办法
8929
查看次数

PyDict_SetItemString 段错误

我正在尝试为 Python3 编写一个简单的 C 扩展,当我尝试将字符串添加到字典时它会出现段错误。这是我的代码:

#include <stdio.h>
#include <Python.h>



int main() {
    PyObject* dict_p = PyDict_New();
    char *val = "idjewijjd";
    PyObject* val_p = PyUnicode_FromString(val);
    const char *key = "dhsjdshj";

    for (int j=0; j<8; j++) { 
        printf("%d\n", PyUnicode_READ_CHAR(val_p,j));
    }

    int r = PyDict_SetItemString(dict_p, key, val_p);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我像这样编译gcc t.c $(python3-config --includes --libs) 并运行它。我得到以下输出:

$ ./a.out 
105
100
106
101
119
105
106
106
Segmentation fault (core dumped)
Run Code Online (Sandbox Code Playgroud)

这是 gdb 回溯:

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff78d9b38 in PyUnicode_InternInPlace …
Run Code Online (Sandbox Code Playgroud)

c python python-c-api

2
推荐指数
1
解决办法
576
查看次数

Python C API:未在此范围内声明 T_INT

我正在按照Python API 的官方教程在 C++ 中为 Python 创建一个简单的扩展类型。但是我无法成功编译我的代码。因为当我T_INT在我的代码中使用时,我收到一个错误说'T_INT' was not declared in this scope。我忘了什么吗?我在教程中找不到答案。

这是我的 C++ 代码:

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

typedef struct {
    PyObject_HEAD
    int num;
} MyObject;

static PyMemberDef MyMembers[] = { 
    { "num", T_INT, offsetof(MyObject, num), 0, NULL },
    { NULL }
};

static PyTypeObject MyType = []{ 
    PyTypeObject ret = { 
        PyVarObject_HEAD_INIT(NULL, 0)
    };  
    ret.tp_name = "cpp.My";
    ret.tp_doc = NULL;
    ret.tp_basicsize = sizeof(MyObject);
    ret.tp_itemsize = 0;
    ret.tp_flags = Py_TPFLAGS_DEFAULT; …
Run Code Online (Sandbox Code Playgroud)

c++ python python-c-api python-3.x

2
推荐指数
1
解决办法
797
查看次数

如何访问 c 扩展中的 numpy 多维数组?

我一直在努力理解 C 扩展中对 numpy 数组的访问,但我很难理解文档。

编辑:这是我想移植到 c 的代码(grav 函数)

import numpy as np

def grav(p, M):
    G = 6.67408*10**-2     # m³/s²T
    l = len(p[0])
    a = np.empty(shape=(2, l))
    a[:, 0] = 0
    for b in range(1, l):
        # computing the distance between body #b and all previous
        d = p[:, b:b+1] - p[:, :b]
        d2 = (d*d).sum(axis=0)
        d2[d2==0] = 1
        XXX = G * d * d2**(-1.5)

        # computing Newton formula : 
        # acceleration undergone by b from all previous …
Run Code Online (Sandbox Code Playgroud)

python python-c-api numpy-ndarray

2
推荐指数
1
解决办法
990
查看次数

如何检查PyObject是否为列表?

我是Python / C API的新手,虽然我可以使用一些基本功能,但我仍在为此而苦苦挣扎。

PyObject* sum_elements(PyObject*, PyObject *o) 
{
    Py_ssize_t n = PyList_Size(o);
    long total = 0;
    if (n < 0)
    {
        return PyLong_FromLong(total);
    }
    PyObject* item;
    for (int i = 0; i < n; i++) 
    {
        item = PyList_GetItem(o, i);
        if (!PyLong_Check(item)) continue;
        total += PyLong_AsLong(item);
    }
    return PyLong_FromLong(total);
}
Run Code Online (Sandbox Code Playgroud)

基本上,这是文档页面上介绍中的功能。它应该接收一个python列表并返回所有元素的总和。如果我通过一个列表,该函数工作正常,如果我通过其他内容,但是出现错误消息

SystemError: c:\_work\5\s\objects\listobject.c:187: bad argument to internal function
Run Code Online (Sandbox Code Playgroud)

这种情况应该由if (n<0)语句处理,如果传递的对象不是列表,则n为-1。

我通过以下方式绑定功能:

static PyMethodDef example_module_methods[] = {
    { "sum_list", (PyCFunction)sum_elements, METH_O, nullptr},
    { nullptr, nullptr, 0, nullptr } …
Run Code Online (Sandbox Code Playgroud)

c++ python python-c-api

2
推荐指数
1
解决办法
200
查看次数

pip 如何告诉 Python 如何导入 C 扩展

sysv_ipc我希望以便携的方式使用该库。

我安装了它:

pip3 install sysv_ipc

然后从Python:

import sysv_ipc
sysv_ipc.__file__

# Output:
# /home/x/.local/lib/python3.9/site-packages/sysv_ipc.cpython-39-x86_64-linux-gnu.so
Run Code Online (Sandbox Code Playgroud)

如果我将该文件复制到文件夹(pip uninstall库),然后从该文件夹打开 python 并尝试相同的导入,则会失败。

我尝试检查还安装了哪些内容,结果发现:

/home/x/.local/lib/python3.9/site-packages/sysv_ipc-1.1.0.dist-info
/home/x/.local/lib/python3.9/site-packages/sysv_ipc.cpython-39-x86_64-linux-gnu.so
/home/x/.local/lib/python3.9/site-packages/sysv_ipc-1.1.0.dist-info/INSTALLER
/home/x/.local/lib/python3.9/site-packages/sysv_ipc-1.1.0.dist-info/LICENSE
/home/x/.local/lib/python3.9/site-packages/sysv_ipc-1.1.0.dist-info/METADATA
/home/x/.local/lib/python3.9/site-packages/sysv_ipc-1.1.0.dist-info/RECORD
/home/x/.local/lib/python3.9/site-packages/sysv_ipc-1.1.0.dist-info/REQUESTED
/home/x/.local/lib/python3.9/site-packages/sysv_ipc-1.1.0.dist-info/WHEEL
/home/x/.local/lib/python3.9/site-packages/sysv_ipc-1.1.0.dist-info/top_level.txt
Run Code Online (Sandbox Code Playgroud)

我也没有在setup.py中找到线索。

我想弄清楚的是——

sysv_ipcpip 如何/在哪里与要从该特定文件导入的Python 相关?

pip python-c-api python-import python-3.x python-internals

2
推荐指数
1
解决办法
885
查看次数

预计算对数组的跨步访问模式会产生更差的性能吗?

我为 numpy 库编写了一个 c 扩展,用于计算特定类型的 bincount。由于缺少更好的名称,我们调用它fast_compiled并将方法签名放在numpy/core/src/multiarray/multiarraymodule.c里面array_module_methods

{"fast_compiled", (PyCFunction)arr_fast_compiled,
    METH_VARARGS | METH_KEYWORDS, NULL},
Run Code Online (Sandbox Code Playgroud)

以及numpy/core/src/multiarray/compiled_base.c(和compiled_base.h)中的实际实现:

NPY_NO_EXPORT PyObject *
arr_fast_compiled(PyObject *NPY_UNUSED(self), PyObject *args, PyObject *kwds)
{
    PyObject *list_obj = NULL, *strides_obj = Py_None;
    PyArrayObject *list_arr = NULL, *ans = NULL, *strides_arr = NULL;

    npy_intp len, ans_size, total_size;
    npy_intp i, j, k;
    double *dans, *weights;
    npy_intp* strides;

    static char *kwlist[] = {"weights", "strides", NULL};

    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", 
                kwlist, &list_obj, &strides_obj)) {
            goto fail; …
Run Code Online (Sandbox Code Playgroud)

c python numpy python-c-api

2
推荐指数
1
解决办法
77
查看次数

Python扩展返回的对象礼节

我正在编写一个python扩展来提供对Solaris kstat数据的访问(与运送perl库Sun :: Solaris :: Kstat的精神相同),我有一个关于有条件地返回列表或单个对象的问题.python用例看起来像:

    cpu_stats = cKstats.lookup(module='cpu_stat')
    cpu_stat0 = cKstats.lookup('cpu_stat',0,'cpu_stat0')

正如它当前实现的那样,lookup()返回匹配的所有kstat对象的列表.第一种情况会产生一个对象列表(尽可能多的是CPU),第二种情况会完全指定一个kstat,并返回一个包含一个kstat的列表.

我的问题是,当只有一个匹配时,返回单个对象的形式很差,而当有多个匹配时,返回列表?

谢谢你的周到答案!我的python-fu很弱但是因为像你这样的人而变得越来越强大.

python python-c-api

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

如何解决 AMD64 Win Python35_d.lib 中缺少 PyModule_Create2 的问题?

我正在尝试调试一个在 32 位 Python 2.7 中运行良好的扩展模块,但在 64 位 Python 3.5 中却不是那么好。

我使用了 Python.org 的 AMD64 Web 安装程序,但在我得到的链接中

__imp_PyModule_Create2 (referenced in libboost_python-vc120-mt-gd-1_57.lib(module.obj))
Run Code Online (Sandbox Code Playgroud)

未解决。这是唯一未解决的符号。

这是故意的吗?我看到一个旧的错误报告,它似乎表明稳定 ABI 免于调试版本。(这就是为什么我在 SO 上发帖而不是提交错误报告)

如果是故意的,是否预计我会先与 python35_d.lib 链接,然后与 python35.lib 链接,还是有另一种方法来解决这个问题?

c python python-c-api python-c-extension debug-mode

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