我在网上搜索过,似乎无法找到文档甚至是PyAPI_DATA()的简单解释(即使它在Python头文件中使用并在python.org上引用).任何人都可以解释这是什么或指向我忽略的文档?
谢谢.
我在 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)
我还没有找到如何提取异常,或者......没有对 …
我正在编写一个将返回多个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)
但是,有没有更短的方法来做到这一点?
如何从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中没有PyStringObject或PyString_AsString.不是吗?
如果我具有以下函数,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变量。
是否有可能定义一个类__getitem__,需要一个tuple使用Python C-API的说法?的sq_item成员
必须是的tp_as_sequence成员,所以我不知道该怎么做。(但我认为NumPy会这样做。)PyTypeObjectssizeargfuncndarray
我正在尝试传递对象
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
当我从不同的 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) Numpy数组,即扩展类型(也称为使用扩展C API定义),声明Python解释器范围之外的其他字段(例如data属性Buffer Structure,如Numpy的数组接口中所记录的那样.
能够序列化它,Python 2曾经使用该__reduce__函数作为pickle协议的一部分,如文档中所述,并在此解释.
但是,即使__reduce__仍然存在于Python 3中,该Pickle protocol部分(以及更为Pickling and unpickling extension types复杂的部分)已从文档中删除,因此不清楚它是做什么的.
此外,还有与酸洗扩展类型相关的其他条目:
Pickle interface constructor registration for extension types,但copyreg模块本身没有提及扩展类型.那么,所有这些与Numpy数组有什么关系:
__reduce__告知Python如何腌制它们(或copyreg)?Numpy对象仍然暴露一个__reduce__方法,但可能是出于兼容性原因.buffer protocol),所以为了挑选numpy数组,不需要任何补充吗?我正在构建一个使用“第三方”库的 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) python ×10
python-c-api ×10
c ×4
python-3.x ×3
api ×1
c++ ×1
numpy ×1
pickle ×1
pyside ×1
return ×1
setuptools ×1
tuples ×1
winapi ×1