无论如何,有没有办法从 gdb 中的 corefile 中发现 PyObject* 的 python 值
我正在尝试使用 C API 构建 Python 字典,但似乎不可能(Py_BuildValue 返回 NULL 对象)使用 PyObject* 作为值。我有这样的情况:
#include <python3.5/Python.h>
...
PyObject *myList = PyList_New(1);
PyList_SetItem(myList, 0, Py_BuildValue("i", 1));
dict = Py_BuildValue("{siso}",
"anInt", myInt,
"aList", mylist);
Run Code Online (Sandbox Code Playgroud)
我正在寻找一种适用于列表通用大小的解决方案。我在官方文档中没有找到任何有关此内容的信息,并且还用谷歌搜索了几个小时。有人可以帮助我吗?提前致谢
我有一个接收并接受 PyCapsule 对象的 C 扩展。
在我的 python 包装器中,如何检查 python 对象是否属于 PyCapsule 类型对象?
>>> # My C extension
>>> foo = Foo()
>>> capsule = foo.to_capsule() # returns a PyCapsule object from the C extension
>>> capsule
<capsule object "foo" at 0xf707df08>
>>> type(capsule)
<class 'PyCapsule'>
isinstance(capsule, PyCapsule)
NameError: name 'PyCapsule' is not defined
Run Code Online (Sandbox Code Playgroud)
我想做的是编写一个类似的函数:
def push_capsule(capsule):
# check that the `capsule` is of type PyCapsule
# c_extension.push_capsule(capsule)
Run Code Online (Sandbox Code Playgroud) 我有一些类似于下面的代码。该代码泄漏,我不知道为什么。泄漏的是在 C 代码中简单创建 Python 类实例。我用来检查泄漏的函数是create_n_times下面定义的,它只是创建新的 Python 实例并在循环中取消引用它们。
这本身并不是 MWE,而是示例的一部分。为了更容易理解,代码的作用是:
set_ip_settings_type.create_n_times然后,调用C 扩展函数,该函数创建和销毁nPython 数据类的实例。有人可以帮忙吗?
在Python中:
import c_api
@dataclass
class IpSettings:
ip: str
port: int
dhcp: bool
c_api.set_ip_settings_type(IpSettings)
c_api.generate_n_times(100000)
Run Code Online (Sandbox Code Playgroud)
在 C++ 中,我将以下代码编译为名为的 Python 扩展c_api(它是该库定义的一部分):
#include <Python.h>
// ... Other functions including a "PyInit" function
extern "C" {
PyObject* ip_settings_type = NULL;
PyObject* set_ip_settings_type(PyObject* tp)
{
Py_XDECREF(ip_settings_type);
Py_INCREF(tp);
ip_settings_type = tp;
return Py_None;
}
PyObject* create_n_times(PyObject* n)
{
long n_ = PyLong_AsLong(n); …Run Code Online (Sandbox Code Playgroud) 我阅读了我能找到的关于NumPy C API的文档,但仍然无法确定是否有可能使用C API构建矩阵对象 - 而不是二维数组.该函数用于处理数学矩阵,如果用户调用矩阵乘法,忘记将数值从数组转换为矩阵(乘法和取幂是矩阵子类的唯一区别),我不希望得到奇怪的结果.
这是我最近两个问题的组合:
[1] C中的Python实例方法
[2] 如何在Python中重定向stderr?
我想从python脚本中记录stdout和stderr的输出.
我想问的是,根据[1]创建一个新类型似乎相当复杂.如果不需要将新类型公开给Python,它是否简化了事情,即它只存在于C中?
我的意思是,当Python打印出来时会转到"Objects/fileobject.c",而在"PyFile_WriteObject"中它会检查是否可以写入其参数:
writer = PyObject_GetAttrString(f, "write");
if (writer == NULL)
...
Run Code Online (Sandbox Code Playgroud)
此外,有可能像这样得到stdout和stderr:
PyObject* out = PySys_GetObject("stdout");
PyObject* err = PySys_GetObject("stderr");
Run Code Online (Sandbox Code Playgroud)
我的问题是,是否有可能构造必要的PyObject,它满足上面的'PyObject_GetAttrString(f,"write")'并且可以调用,所以我可以写:
PySys_SetObject("stdout", <my writer object / class / type / ?>);
Run Code Online (Sandbox Code Playgroud)
http://docs.python.org/c-api/sys.html?highlight=pysys_setobject#PySys_SetObject
这样,就没有必要将新的"writer类型"暴露给Python脚本的其余部分,所以我认为编写代码可能有点简单......?
我在C中有一个应用程序,在某些时候我需要解决非线性优化问题.不幸的是,AFAIK在C中的资源非常有限(请让我知道其他情况).但是在Python中使用它很简单,例如scipy.optimize.minimize.
当我试图这样做时,我遇到了一些看似非常频繁的陷阱,例如Python.h找不到,模块没有加载,函数调用时出现分段错误等.
什么是快速简便的第一计时器链接这两个程序的方式?
我正在使用python-C api重写一个最初用C编写的python模块到Cython.模块也使用NumPy.该项目的一个主要挑战是保持模块的当前速度,并且它应该适用于所有Numpy数据类型.我想使用融合数据类型使其通用但我担心,因为它对性能的瓶颈影响.有没有其他技术可以用来代替融合类型,我可以使用它来实现速度和通用代码.
以下程序,当链接到python 2.7.13并在Windows 10上运行缓慢但稳定地泄漏内存.
#include <Python.h>
#include <iostream>
int main()
{
std::cout << "Python version: " << PY_VERSION << std::endl;
while (true)
{
Py_Initialize();
//PyGC_Collect();
Py_Finalize();
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
有趣的是,似乎并非每次迭代都会泄漏内存.但我所看到的是,无论泄漏如何,python打印缓慢的引用计数增加了每次迭代大约90次的(非常量)计数.使用Visual Studio诊断工具我发现泄漏来自于PyImport_ImportModule()从磁盘读取已编译模块时的调用(实际调用堆栈深度为几级).
是否还需要我不知道的额外清理步骤?或者有什么关于Python垃圾收集器可能导致这一点,它不是一个"真正的"内存泄漏?
我正在.pyd使用Visual Studio 2015 C ++项目和Python 2.7 32位构建Python扩展()。
这是我的.cpp文件:
#include <Python.h>
static PyObject* GetTwoInts(PyObject* self, PyObject* args)
{
srand(time(NULL));
int random1 = rand() % 10;
int random2 = rand() % 10;
PyObject * python_val = Py_BuildValue("ii", random1, random2);
return python_val;
}
static PyObject* GetListTwoInts(PyObject* self, PyObject* args)
{
srand(time(NULL));
int random1 = rand() % 10;
int random2 = rand() % 10;
PyObject *val1 = PyInt_FromLong(random1);
PyObject *val2 = PyInt_FromLong(random2);
PyObject *result = PyList_New(2);
PyList_SetItem(result, 0, val1);
PyList_SetItem(result, …Run Code Online (Sandbox Code Playgroud) python ×10
python-c-api ×10
c ×3
c++ ×3
cpython ×3
numpy ×2
cython ×1
memory-leaks ×1
pyobject ×1
python-3.x ×1
scipy ×1
stdout ×1