标签: python-c-api

如何在C扩展中创建自定义Python异常类型?

我在C中编写Python模块.我需要报告内置Python异常无法描述的错误.因此,我希望抛出我自己的类型的例外.问题是,Python策略是从BaseException类派生所有异常.我知道如何创建派生类型对象(分配给tp_base memeber),但我不知道如何获取对BaseException类型对象的引用.PyExc_BaseException是对PyObject的引用,表示类,而不是类型对象.

如何从C代码中抛出自定义Python异常?

c python exception python-c-api

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

从C函数构建PyObject*?

我正在将Python嵌入到我正在制作的C++库中.我希望用户能够以函数指针的形式传递C函数,PyObject* (fpFunc*)(PyObject*,PyObject*);以便我可以在嵌入式Python中使用这些函数.

所以我有一个函数指针,我知道可以将这个函数作为模块的方法使用PyMethodDef结构并将其传递给它Py_InitModule("module", ModMethods);,从而获得一个PyObject* module我可以轻松地从中获取函数的函数.

但是,我真正欣赏的是能够动态创建此功能,而不必每次都重新创建另一个模块.

我已经研究了Python文档,以及一些Python头文件,想到了一个没有真正成功的hacky方法...但我想知道是否有更传统的方法来做到这一点.

根据我的理解,每个函数都属于一个模块,甚至__builtin__,所以我想我至少需要模块.

有关如何实现这一点的任何想法?

c python python-c-api

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

使用Python/C API传递C指针

我是Python/C API的新手...我正在尝试为我的C程序添加新功能,其中我可以将python嵌入其中并同时扩展功能,以便嵌入式解释器可以执行将与之交互的脚本作为我的C程序的一部分编写的扩展python模块.我的C程序没有全局变量.我想保持这种方式; 同时为了向Cthon公开C功能,看来扩展C函数至少需要访问全局变量来访问程序的状态.我该如何解决这个问题?

例如,这是我如何计划嵌入从main调用PYINTERFACE_Initialize的地方

void PYINTERFACE_Initialize(State *ptr, FILE *scriptFile, const char* scriptFileName)
{
    Py_Initialize();
    PyObject *module = Py_InitModule("CInterface", CInterfaceMethods);
    if (PyRun_SimpleFileEx(scriptFile, scriptFileName, 1) != 0)
    {
        printf("PYINTERFACE script execution failed!\n");
    }
    **//ADD State *ptr TO module**      
}
Run Code Online (Sandbox Code Playgroud)

这是扩展功能:

static PyObject*
CInterface_GetStateInfo(PyObject *self, PyObject *args)
{
    const char *printStr;
    double stateInfo;
    State *ptr;

    if(!PyArg_ParseTuple(args, "s", &printStr))
    {
        return NULL;
    }
    printf("Received %s\n", printStr);

    **//RETRIEVE State *ptr FROM self**      

    stateInfo = ptr->info;
    return Py_BuildValue("d", currentTime);
}
Run Code Online (Sandbox Code Playgroud)

这是通过State*ptr的最干净的方法吗?我当然不认为需要将内部状态暴露给python.我曾考虑使用胶囊,但似乎并不是胶囊的意图支持这种行为.

提前致谢!V

python python-c-api

11
推荐指数
2
解决办法
9466
查看次数

C数组到PyArray

我在不使用Cython的情况下编写Python C-Extension.

我想在C中分配一个double数组,在内部函数中使用它(恰好在Fortran中)并返回它.我指出C-Fortran接口在C中完美运行.

static PyObject *
Py_drecur(PyObject *self, PyObject *args)
{
  // INPUT
  int n;
  int ipoly;
  double al;
  double be;

  if (!PyArg_ParseTuple(args, "iidd", &n, &ipoly, &al, &be))
    return NULL;

  // OUTPUT
  int nd = 1;
  npy_intp dims[] = {n};
  double a[n];
  double b[n];
  int ierr;

  drecur_(n, ipoly, al, be, a, b, ierr);

  // Create PyArray
  PyObject* alpha = PyArray_SimpleNewFromData(nd, dims, NPY_DOUBLE, a);
  PyObject* beta = PyArray_SimpleNewFromData(nd, dims, NPY_DOUBLE, b);

  Py_INCREF(alpha);
  Py_INCREF(beta);

  return Py_BuildValue("OO", alpha, beta);
}
Run Code Online (Sandbox Code Playgroud)

我调试了这段代码,当我尝试从a创建alpha时,我遇到了Segmentation错误.到那里一切正常.功能drecur_工作,如果删除它我会遇到同样的问题.

现在,围绕C数据定义PyArray的标准方法是什么?我找到了文档,但没有很好的例子.还有,内存泄漏怎么样?返回之前INCREF是否正确,以便保留alpha和beta的实例?那些不再需要的解除分配怎么样?

编辑 …

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

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

Python C API:如何获取异常的字符串表示?

如果我这样做(例如)

 open("/snafu/fnord")
Run Code Online (Sandbox Code Playgroud)

在Python中(并且该文件不存在),我得到一个追溯和消息

 IOError: [Errno 2] No such file or directory: '/snafu/fnord'
Run Code Online (Sandbox Code Playgroud)

我想用Python的C API获取上面的字符串(即嵌入在C程序中的Python解释器).我需要它作为一个字符串,而不是输出到控制台.

随着PyErr_Fetch()我可以得到异常和值的类型对象.对于上面的示例,值是一个元组:

 (2, 'No such file or directory', '/snafu/fnord')
Run Code Online (Sandbox Code Playgroud)

从我获得的信息PyErr_Fetch()到Python解释器显示的字符串有一个简单的方法吗?(不涉及为每个异常类型自己构造这样的字符串.)

python exception python-c-api

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

如何在Python C扩展中为__init__指定docstring

也许是一个愚蠢的问题:如何__init__在编写C扩展时为特殊函数指定docstring ?对于普通方法,方法表提供了文档字符串.当我尝试帮助时,会显示以下自动生成的文档(myclass):

  __init__(...)
      x.__init__(...) initializes x; see help(type(x)) for signature
Run Code Online (Sandbox Code Playgroud)

但这是我想要覆盖的.

python docstring python-c-api python-extensions

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

如何将数组从C传递给嵌入式python脚本

我遇到了一些问题,希望得到一些帮助.我有一个片段代码,用于嵌入python脚本.这个python脚本包含一个函数,它希望接收一个数组作为参数(在这种情况下,我在python脚本中使用numpy数组).我想知道如何将数组从C传递给嵌入式python脚本作为脚本中函数的参数.更具体地说,有人可以向我展示一个简单的例子.

python embedding python-c-api

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

Python C API如何将结构数组从C传递给Python

对于我正在创建的python模块,我想向python用户传递一个这样的结构数组:

struct tcpstat
{
    inet_prefix local;
    inet_prefix remote;
    int     lport;
    int     rport;
    int     state;
    int     rq, wq;
    int     timer;
    int     timeout;
    int     retrs;
    unsigned    ino;
    int     probes;
    unsigned    uid;
    int     refcnt;
    unsigned long long sk;
    int     rto, ato, qack, cwnd, ssthresh;
};
Run Code Online (Sandbox Code Playgroud)

我认为那Py_BuildValues是我正在寻找的功能.但似乎不是.查看Python文档,我找到了缓冲协议.但这是我第一次开发python模块,官方文档对我没有多大帮助.

缓冲协议是我问题的最佳解决方案吗?如果是这样,我怎么能将我的数组从C返回到python?

c python python-c-api

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

使用C扩展python:将列表传递给PyArg_ParseTuple

我一直在尝试用C扩展python,到目前为止,基于文档,我在编写小型C函数和使用Python扩展它方面取得了相当大的成功.

但是,我现在遇到了一个相当简单的问题 - 我无法找到解决方案.所以,我想做的是传递double list给我的C函数.例如,要传递int,我执行以下操作:

int squared(int n)
{
    if (n > 0)
        return n*n;
    else
        return 0;
}

static PyObject*
squaredfunc(PyObject* self, PyObject* args)
{
    int n;

    if (!PyArg_ParseTuple(args, "i", &n))
        return NULL;

    return Py_BuildValue("i", squared(n));
}
Run Code Online (Sandbox Code Playgroud)

这将int n没有任何问题传递给我的C函数命名squared.

但是,如何将一个传递list给C函数?我确实尝试谷歌并阅读文档,到目前为止,我还没有找到任何有用的东西.

如果有人能指出我正确的方向,我真的很感激.

谢谢.

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

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

使用Python和C api进行多线程处理

我有一个C++程序,它使用C api来使用我的Python库. Python库和C++代码都是多线程的.

特别是,C++程序的一个线程实例化一个继承自的Python对象threading.Thread.我需要所有的C++线程能够调用该对象上的方法.

从我第一次尝试(我天真地只是从主线程实例化对象,然后等待一段时间,然后调用方法)我注意到,执行返回后,与刚刚创建的对象关联的Python线程的执行就会停止到C++程序.

如果执行仍然使用Python(例如,如果我调用PyRun_SimpleString("time.sleep(5)");),Python线程的执行将在后台继续执行,一切正常,直到等待结束并执行返回到C++.

我显然做错了什么.我应该怎么做才能让两个我的C++和Python的多线程和能够彼此很好地工作?我以前没有这方面的经验所以请不要假设!

c++ python multithreading python-c-api

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