铸造PyCFunctionWithKeywords

问题描述:

最近我一直在包装的python很多C++代码,我觉得这是块(直接从python documentation拍摄)有些令人担忧:铸造PyCFunctionWithKeywords

static PyMethodDef keywdarg_methods[] = { 
/* The cast of the function is necessary since PyCFunction values 
* only take two PyObject* parameters, and keywdarg_parrot() takes 
* three. 
*/ 
{"parrot", (PyCFunction)keywdarg_parrot, METH_VARARGS | METH_KEYWORDS, 
"Print a lovely skit to standard output."}, 
{NULL, NULL, 0, NULL} /* sentinel */ 
}; 

的问题是线,将kwarg_parrot类型PyCFunctionWithKeywords转换为PyCFunction

从C++背景的(并考虑到我包裹C++代码),它似乎是错误使用C样式转换。我试过static_castdynamic_cast,这两者都会导致编译器抱怨(有很好的理由,这在一般意义上确实是不安全的)。唯一可行的C++选项似乎是reinterpret_cast,但据我所知,这是C风格演员的更详细版本。

当然,上面的包装在extern "C"块中,所以也许C方式是正确的方法。有没有人有更好的想法? (我很想看看会是可以自动生成基于关键词的文档字符串的解决方案。)

不幸的是,像Boost.Python的和呷解决方案是假表。 (我是一个丑陋的框架内工作)

+0

C++中的“C cast”被称为reinterpret_cast,可以随意使用它。 – 2012-02-29 10:10:37

+0

我不认为有一种方法可以避免演员(C风格或重新解释),因为Python包装是按照这种方式设计的。你应该传递各种函数指针,但你必须让它们看起来像一个PyCFunction。深入下来,它们将根据您设置的选项(如“METH_VARARGS”)重新解释。 – jogojapan 2012-02-29 10:20:58

+0

您究竟想要如何构建文档字符串?我完全不理解。 – jogojapan 2012-02-29 10:21:30

主要Python的实现是用C写的,而不是C++。

因此,评估keywdarg_methods[]的libpython代码是用C编写的,并且通过C调用约定调用keywdarg_parrot

如果你想C++和Python风格的融合,找到一种方法,而不是使用Boost.Python的。或者也许是cython。

+2

不,我也像Shep一样包装了很多C++。这是有效的,但实际上类型转换是丑陋的。 – jogojapan 2012-02-29 10:17:32

+0

Boost.Python的主要问题是让它能够与许多不同版本的python和许多不同的计算集群一起工作。我们经常编写发送到集群的代码,并在那里构建,然后使用可能缺少相应的Boost.Python版本的python版本运行。将构建系统指向Python头文件通常很困难,更别说构建boost库了。 – Shep 2012-02-29 11:23:07

+0

也许你的自定义C包装是完全正确的。 – 2012-03-01 13:02:28

PyMethodDef是Python C API,所以我只想用一个C铸件的一部分。它的工作原理就是所有Python extenaions都在使用的。保持一致。

使用C++与不是Python API中的一部分对象时施放。