标签: python-c-api

PyAPI_DATA()宏的解释?

我在网上搜索过,似乎无法找到文档甚至是PyAPI_DATA()的简单解释(即使它在Python头文件中使用在python.org上引用).任何人都可以解释这是什么或指向我忽略的文档?

谢谢.

c python api python-c-api

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

PyEval_CallObject 偶尔在循环中失败

我在 Python C API 上有点挣扎。我正在调用 python 方法以大约 60hz 进行一些游戏 AI。它大部分时间都可以工作,但每隔一秒左右,对 PyEval_CallObject 的调用就会产生一个 NULL 返回值。如果我正确检测到错误并继续循环,那么下一秒左右一切都会好起来,于是错误再次发生。

我怀疑我在引用计数方面做错了什么,但我无法弄清楚它是什么:

int script_do_ai(struct game_data_t* gd)
{

    PyObject *pAiModule, *pResult;

    float result=0.0;
    pResult = NULL;

    pAiModule = PyImport_Import(PyString_FromString("ai_script"));
Run Code Online (Sandbox Code Playgroud)

是的,我每次迭代都会导入模块。那有必要吗?如果我将 pAiModule 存储为全局变量,大约一秒钟后就会发生严重崩溃。

    pResult = PyEval_CallObject(PyObject_GetAttrString(pAiModule, "do_ai"),
                               Py_BuildValue("f", gd->important_float))  
    if (pResult != NULL)
    {       
        PyArg_Parse(pResult, "f", &result);
        Py_DECREF(pResult);
        ConquerEnemies(result);  //you get the idea
    }
    else  //this happens every 75 or so iterations thru the loop
    {
       if (PyErr_ExceptionMatches(PyExc_SomeException))  //? not sure what to do here
       {
Run Code Online (Sandbox Code Playgroud)

我还没有找到如何提取异常,或者......没有对 …

c python python-c-api

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

在Python C API中返回多重对象的元组

我正在编写一个将返回多个Python对象的本机函数

PyObject *V = PyList_New(0);
PyObject *E = PyList_New(0);
PyObject *F = PyList_New(0);

return Py_BuildValue("ooo", V, E, F);
Run Code Online (Sandbox Code Playgroud)

这编译很好,但是,当我从Python程序调用它时,我收到一个错误:

SystemError:传递给Py_BuildValue的格式错误

怎么能正确完成?

编辑:以下工作

PyObject *rslt = PyTuple_New(3);
PyTuple_SetItem(rslt, 0, V);
PyTuple_SetItem(rslt, 1, E);
PyTuple_SetItem(rslt, 2, F);
return rslt;
Run Code Online (Sandbox Code Playgroud)

但是,有没有更短的方法来做到这一点?

python tuples return python-c-api

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

如何从指向字符串的PyObject获取char*

如何从PyObject中获取指向字符串的char*.例如,这是python脚本,

Test.Connect("272.22.20.65", 1234)
Run Code Online (Sandbox Code Playgroud)

这是C++代码,

static PyObject* Connect(PyObject *self, PyObject *args)
{
    PyObject* pIP;
    PyObject* pPort;

    if (!PyArg_UnpackTuple(args, "Connect", 2, 2, &pIP, &pPort)) 
    {
        return NULL;
    }

    const char* zIP = GetAsString(pIP);
    long iPort      = PyLong_AsLong(pPort);
Run Code Online (Sandbox Code Playgroud)

我想将该IP地址作为char*(GetAsString是一个虚拟函数:D).请注意我使用的是Python 3.1.

PS我不认为这个问题得到了正确答案,因为Python 3中没有PyStringObjectPyString_AsString.不是吗?

python python-c-api python-3.x

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

PyArg_ParseTuple默认参数

如果我具有以下函数,myobj但未传递可选参数,则是否myobj保留NULL或设置为Py_None

static PyObject * myfunc(PyObject * self, PyObject * args) {
    PyObject * myobj = NULL;
    if (!PyArg_ParseTuple(args, "|O", &myobj)) {
        return NULL;
    }
    // ...
}
Run Code Online (Sandbox Code Playgroud)

根据解析参数和建立值

|指示Python参数列表中的其余参数是可选的。与可选参数相对应的C变量应初始化为其默认值-如果未指定可选参数,则PyArg_ParseTuple()不会触及相应C变量的内容。

这适用于PyObject *s吗?显然,它是C中存在的一个指针,因此可以说它是一个C变量,但是它是一个指向python对象的指针,所以也可以说它不算作C变量。

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

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

使用Python C-API具有元组参数的__getitem__方法

是否有可能定义一个类__getitem__,需要一个tuple使用Python C-API的说法?的sq_item成员 必须是的tp_as_sequence成员,所以我不知道该怎么做。(但我认为NumPy会这样做。)PyTypeObjectssizeargfuncndarray

python python-c-api

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

如何在 Python 中处理 PyCapsule 类型

我正在尝试传递对象

QtGui.QWidget.effectiveWinId() 
Run Code Online (Sandbox Code Playgroud)

win32gui.SetWindowLong()
Run Code Online (Sandbox Code Playgroud)

EffectiveWinId() 正在返回:

<capsule object NULL at 0x027C9BF0>
<class 'PyCapsule'>
Run Code Online (Sandbox Code Playgroud)

并且 SetWindowLong() 需要一个 PyHANDLE(文档说它“应该”也接受一个整数)

TypeError: The object is not a PyHANDLE object
Run Code Online (Sandbox Code Playgroud)

所以我的问题是如何从 PyCapsule 对象中获取值并检查它是否为 NULL?似乎 PyCapsule 都是 C 代码的内部 API。

我还发现这个错误与我想要的 Python 2.X PyCObject 类似,它在 Python 3.x 中不存在:http ://srikom.github.io/pyside-bz-archive/show_bug.cgi ?id=523#c18

python winapi python-c-api pyside

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

使用线程调用 Py_Finalize 时出现断言错误(仅限 3.X)

当我从不同的 C 线程调用 C-API 的 Py_Finalize() 而不是我进行 python 调用时,我得到一个错误输出。

我看到的错误是:

Exception ignored in: <module 'threading' from 'C:\\Python34-32\\Lib\\threading.py'>
Traceback (most recent call last):
  File "C:\Python34-32\Lib\threading.py", line 1289, in _shutdown
    assert tlock.locked()
AssertionError:
Run Code Online (Sandbox Code Playgroud)

这只发生在 Python 3.X(用 3.4.2 测试)中,在 Python 2.7 中完全相同的代码没有任何问题。

这是一个最小的例子,它显示了在使用 C 线程时发生的情况,但不是当所有事情都发生在单个 c 线程上时:

#include <iostream>
#include <fstream>
#include <thread>
#include <cassert>

#include <Python.h>

void make_file()
{
   std::fstream file("my_test.py", std::ios::out);
   file << 
      "import threading\n"   << 
      "def my_function():\n" << 
      "    pass\n"             ;
   file.close();
}

void exec()
{
   PyGILState_STATE gstate = PyGILState_Ensure(); …
Run Code Online (Sandbox Code Playgroud)

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

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

Python 3如何知道如何挑选扩展类型,特别是Numpy数组?

Numpy数组,即扩展类型(也称为使用扩展C API定义),声明Python解释器范围之外的其他字段(例如data属性Buffer Structure,如Numpy的数组接口中所记录的那样.
能够序列化它,Python 2曾经使用该__reduce__函数作为pickle协议的一部分,如文档中所述,并在此解释.

但是,即使__reduce__仍然存在于Python 3中,该Pickle protocol部分(以及更为Pickling and unpickling extension types复杂的部分)已从文档中删除,因此不清楚它是做什么的.
此外,还有与酸洗扩展类型相关的其他条目:

  • copyreg,描述为a Pickle interface constructor registration for extension types,但copyreg模块本身没有提及扩展类型.
  • PEP 3118 - 修改缓冲协议,为Python 3发布了一个新的缓冲协议(并且可能自动为这个缓冲协议进行酸洗).
  • 新式课程:可以假设新式课程对酸洗过程有影响.

那么,所有这些与Numpy数组有什么关系:

  1. Numpy数组是否实现了特殊方法,例如__reduce__告知Python如何腌制它们(或copyreg)?Numpy对象仍然暴露一个__reduce__方法,但可能是出于兼容性原因.
  2. Numpy是否使用了Pickle开箱即用的Python的C-API结构(就像新的一样buffer protocol),所以为了挑选numpy数组,不需要任何补充吗?

python numpy pickle python-c-api python-3.x

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

包含和分发带有 Python C 扩展的第三方库

我正在构建一个使用“第三方”库的 C Python 扩展——在本例中,我使用单独的构建过程和工具链构建了一个。调用这个库libplumbus.dylib

目录结构为:

grumbo/
  include/
    plumbus.h
  lib/
    libplumbus.so
  grumbo.c
  setup.py
Run Code Online (Sandbox Code Playgroud)

我的setup.py样子大约是:

from setuptools import Extension, setup

native_module = Extension(
    'grumbo',
    define_macros = [('MAJOR_VERSION', '1'),
                     ('MINOR_VERSION', '0')],
    sources       = ['grumbo.c'],
    include_dirs  = ['include'],
    libraries     = ['plumbus'],
    library_dirs  = ['lib'])


setup(
    name = 'grumbo',
    version = '1.0',
    ext_modules = [native_module] )
Run Code Online (Sandbox Code Playgroud)

由于 libplumbus 是一个外部库,当我运行时,import grumbo我得到:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: dlopen(/path/to/grumbo/grumbo.cpython-37m-darwin.so, 2): Library not loaded: lib/libplumbus.dylib
  Referenced …
Run Code Online (Sandbox Code Playgroud)

c python setuptools python-c-api python-extensions

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