Python的C-API的常数正确性

2024-10-02 18:25:03 发布

您现在位置:Python中文网/ 问答频道 /正文

pythoncapi似乎与字符数组的常量正确性不一致。例如,PyImport_ImportFrozenModule接受char*,而PyImport_ImportModule接受const char*。在

这意味着,在我用一个嵌入式Python解释器编写的C++应用程序中,有时我不得不把我传递给Python API调用的字符串文字仅仅是一个^ {CD1>}(而不是^ {CD2>}),有时我不这样做。

PyObject *os = PyImport_ImportModule("os"); // Works without the const_cast
PyObject *cwd = PyObject_CallMethod(os, const_cast<char*>("getcwd"), NULL); // Accepts char*, not const char*

如果不对字符串文本执行const_cast<char*>(或(char*)),编译器会警告我将字符串文本转换为char*。在

以下是我的问题:

  1. 让一些函数不使用const char*是否有好处/原因(和/或为什么Python API在这方面不一致)?我的理解是,如果函数可以接受字符串文本,它就不能更改char*,所以const修饰符只会加强这一点。我也相信,^ {CD10}}的区分对于C(API编写的)与C++中的(如果我错了)更正并不重要。我的力量是Python,而不是C/C++。pythonapi缺乏“constcorrectification”是因为它在C语言中并不那么重要?(有一个来自2000年的old thread on the python mailing list提出了同样的问题,但似乎没有得到任何结果,这意味着原因可能是某些编译器不支持const。由于许多函数现在有const char*,这似乎不再适用)
  2. >P>因为我对C++的理解有限,所以我不确定我是否要正确地处理字符串文字。我可以选择以下一种方式:

    ^{pr2}$

    哪种方法最好?


更新:

看起来Python3分支正在缓慢地尝试修复const正确性问题。例如,我在上面的示例中使用的PyImport_ImportFrozenModule函数现在在Python3.4中采用了const char*,但是仍然有一些函数只接受char*,比如PyLong_FromString。在


Tags: the函数字符串文本apiospyobject文字
2条回答

Is there an advantage/reason to having some of the functions not take a const char*?

不,看起来像是图书馆设计上的疏忽,或者,就像你说的,遗留问题。不过,他们至少可以让它保持一致!在

My understanding is that if the function can take a string literal, it cannot change the char* so the const modifier would just be reinforcing this.

没错。他们的文档还应该指定函数参数(或者更确切地说,参数的指针对象)在函数调用期间不应该被修改;唉,它目前没有这样说。在

I also believe that the const distinction is not as important for C (for which the API was written) than it is in C++.

嗯,不是,至少据我所知。在

The way I see it, I can either one of the following (I am currently doing the first)

(好的)

Which is the best method do use?

好吧,const_cast至少会确保你是唯一的修改const-的,所以如果你必须选择,我会同意。但是,真的,我不会太在意这个。在

根据python dev的一些邮件列表对话,看起来最初的API只是没有考虑到const的正确性,可能只是因为Guido没有考虑到这一点。追溯到2002年,someone asked如果有人想通过添加常量正确性来解决这个问题,抱怨总是这样做很痛苦:

somefunc(const char* modulename, const char* key)
{
    ... PyImport_ImportModule(const_cast<char*>(modulename)) ...

Guido Van Rossum(Python的创建者)replied(emphasis mine):

I've never tried to enforce const-correctness before, but I've heard enough horror stories about this. The problem is that it breaks 3rd party extensions left and right, and fixing those isn't always easy. In general, whenever you add a const somewhere, it ends up propagating to some other API, which then also requires a const, which propagates to yet another API needing a const, ad infinitum.

有更多的讨论,但没有Guido的支持,这个想法就夭折了。在

9年后,这个话题又出现了。这一次有人只是想知道,为什么有些函数是const正确的,而其他的却不是

We have been adding const to many places over the years. I think the specific case was just missed (i.e. nobody cared about adding const there).

似乎在不破坏向后兼容性的情况下,const-correction已经被添加到C-API中的许多地方(在python3的例子中,它会在某些地方打破与python2的向后兼容性),但从来没有真正的全球性努力来修复它。因此,Python3中的情况更好,但是整个API现在可能还不正确。在

我不认为Python社区有任何处理调用的方法,而不是^ {< CD1>} -正确(在官方^ {A4}中没有提到它),可能是因为没有一个用户与C++代码接口连接C-API。我认为从纯C++最佳实践的角度来看,首选的方法是首选。(我决不是一个C++专家,所以,请接受这一点。)在

相关问题 更多 >