我在C中编写Python模块.我需要报告内置Python异常无法描述的错误.因此,我希望抛出我自己的类型的例外.问题是,Python策略是从BaseException类派生所有异常.我知道如何创建派生类型对象(分配给tp_base memeber),但我不知道如何获取对BaseException类型对象的引用.PyExc_BaseException是对PyObject的引用,表示类,而不是类型对象.
如何从C代码中抛出自定义Python异常?
我正在将Python嵌入到我正在制作的C++库中.我希望用户能够以函数指针的形式传递C函数,PyObject* (fpFunc*)(PyObject*,PyObject*);以便我可以在嵌入式Python中使用这些函数.
所以我有一个函数指针,我知道可以将这个函数作为模块的方法使用PyMethodDef结构并将其传递给它Py_InitModule("module", ModMethods);,从而获得一个PyObject* module我可以轻松地从中获取函数的函数.
但是,我真正欣赏的是能够动态创建此功能,而不必每次都重新创建另一个模块.
我已经研究了Python文档,以及一些Python头文件,想到了一个没有真正成功的hacky方法...但我想知道是否有更传统的方法来做到这一点.
根据我的理解,每个函数都属于一个模块,甚至__builtin__,所以我想我至少需要模块.
有关如何实现这一点的任何想法?
我是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
我在不使用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的实例?那些不再需要的解除分配怎么样?
编辑 …
如果我这样做(例如)
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解释器显示的字符串有一个简单的方法吗?(不涉及为每个异常类型自己构造这样的字符串.)
也许是一个愚蠢的问题:如何__init__在编写C扩展时为特殊函数指定docstring ?对于普通方法,方法表提供了文档字符串.当我尝试帮助时,会显示以下自动生成的文档(myclass):
__init__(...)
x.__init__(...) initializes x; see help(type(x)) for signature
Run Code Online (Sandbox Code Playgroud)
但这是我想要覆盖的.
我遇到了一些问题,希望得到一些帮助.我有一个片段代码,用于嵌入python脚本.这个python脚本包含一个函数,它希望接收一个数组作为参数(在这种情况下,我在python脚本中使用numpy数组).我想知道如何将数组从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,到目前为止,基于文档,我在编写小型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++程序,它使用C api来使用我的Python库. Python库和C++代码都是多线程的.
特别是,C++程序的一个线程实例化一个继承自的Python对象threading.Thread.我需要所有的C++线程能够调用该对象上的方法.
从我第一次尝试(我天真地只是从主线程实例化对象,然后等待一段时间,然后调用方法)我注意到,执行返回后,与刚刚创建的对象关联的Python线程的执行就会停止到C++程序.
如果执行仍然使用Python(例如,如果我调用PyRun_SimpleString("time.sleep(5)");),Python线程的执行将在后台继续执行,一切正常,直到等待结束并执行返回到C++.
我显然做错了什么.我应该怎么做才能让两个我的C++和Python的多线程和能够彼此很好地工作?我以前没有这方面的经验所以请不要假设!