[英]Keyword parsing in C/C++ extension for Python 3
I am currently trying to implement a Python module using C++. 我目前正在尝试使用C ++实现Python模块。 Official Python 3 docs provide an example here , but to my surprise the code provided there throws errors in my Visual Studio 2017! 官方Python 3文档在此处提供了一个示例,但令我惊讶的是,其中提供的代码在我的Visual Studio 2017中引发了错误!
If you take a look at Custom_init
function implementation, you will see a function call PyArg_ParseTupleAndKeywords
that takes several arguments, including a keyword array kwlist
declared 3 lines above (Example copy-pasted below): 如果您看一下Custom_init
函数的实现,您将看到一个函数调用PyArg_ParseTupleAndKeywords
,它PyArg_ParseTupleAndKeywords
多个参数,包括上面3行声明的关键字数组kwlist
(下面的示例复制粘贴):
static int
Custom_init(CustomObject *self, PyObject *args, PyObject *kwds)
{
static char *kwlist[] = {"first", "last", "number", NULL};
PyObject *first = NULL, *last = NULL, *tmp;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|UUi", kwlist,
&first, &last,
&self->number))
return -1;
if (first) {
tmp = self->first;
Py_INCREF(first);
self->first = first;
Py_DECREF(tmp);
}
if (last) {
tmp = self->last;
Py_INCREF(last);
self->last = last;
Py_DECREF(tmp);
}
return 0;
}
However upon trying to declare a kwlist
of my own like in example above, VS2017 throws the following error: 但是在尝试像上面的示例一样声明自己的kwlist
时,VS2017引发以下错误:
a value of type "const char *" cannot be used to initialize an entity of type "char *" 类型“ const char *”的值不能用于初始化“ char *”类型的实体
The simple thing would be to declare my own kwlist
as const
, but PyArg_ParseTupleAndKeywords
expects kwlist
as char *
. 简单的事情是将我自己的kwlist
声明为const
,但是PyArg_ParseTupleAndKeywords
期望kwlist
为char *
。 (Documentation here ) ( 此处的文档)
Is there a way to deal with this without resorting to extremes like const_cast
? 有没有一种方法可以解决此问题而无需求助于const_cast
极端方法?
Thank you. 谢谢。
EDIT: 编辑:
One of the comments below suggested to simply copy from const char*
to char*
and I believe that will be the simplest approach to resolve this. 以下评论之一建议将其简单地从const char*
复制到char*
,我相信这将是解决此问题的最简单方法。
I cannot think of anything less horrible than 我想不出比这更可怕的了
static char first[] = "first";
static char last[] = "last";
static char number[] = "number";
static char *kwlist[] = {first, last, number, NULL};
You can store the strings as std::string
s, and then use std::string::data
to get your char *
s 您可以将字符串存储为std::string
,然后使用std::string::data
来获取char *
s
static int
Custom_init(CustomObject *self, PyObject *args, PyObject *kwds)
{
static std::array<std::string, 4> keywords { "first", "last", "number", "" };
std::array<char *, 4> kwlist;
std::transform(keywords.begin(), keywords.end(), kwlist.begin(), [](auto & str){ return str.data(); });
PyObject *first = nullptr;
PyObject *last = nullptr;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|UUi", kwlist.data(),
&first, &last,
&self->number))
return -1;
if (first) {
auto tmp = self->first;
Py_INCREF(first);
self->first = first;
Py_DECREF(tmp);
}
if (last) {
auto tmp = self->last;
Py_INCREF(last);
self->last = last;
Py_DECREF(tmp);
}
return 0;
}
Alternatively, you can use offsets into a single string literal 或者,您可以在单个字符串文字中使用偏移量
static char keywords[] = "first\0last\0number\0\0";
static char * kwlist = { keywords, keywords + 6, keywords + 11, keywords + 18 };
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.