最近我在python中包装了很多C ++代码,我发现这个块(直接来自python documentation)有点令人不安:
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_cast
和dynamic_cast
,这两个都会导致编译器抱怨(有充分的理由,这在一般意义上说这确实是一个不安全的演员)。唯一可行的C ++选项似乎是reinterpret_cast
,但据我所知,这是一个更加冗长的C风格版本。
当然,上面的 包装在extern "C"
块中,所以C方式可能是正确的方法。有没有人有更好的想法? (我真正希望看到的是一个可以根据关键字自动生成文档字符串的解决方案。)
不幸的是,像Boost.Python和SWIG这样的解决方案已不在考虑范围之内。 (我在一个丑陋的框架内工作)
答案 0 :(得分:1)
主要的Python实现是用C语言编写的,而不是C ++。
因此,评估keywdarg_methods[]
的libpython代码是用C语言编写的,并通过C调用约定调用keywdarg_parrot
。
如果您希望C ++样式与Python集成,请找到使用boost.python的方法。或者也许是cython。
答案 1 :(得分:1)
PyMethodDef是Python C API的一部分,所以我只使用C强制转换。它的工作原理和所有Python扩展都在使用。保持一致。
在处理不属于Python API的对象时使用C ++强制转换。