【发布时间】:2014-01-02 02:38:06
【问题描述】:
看来 Python C API 与字符数组的 const 正确性不一致。例如,PyImport_ImportFrozenModule 接受 char*,而 PyImport_ImportModule 接受 const char*。
所有这一切的含义是,在我使用嵌入式 Python 解释器编写的 C++ 应用程序中,有时我必须将传递给 Python API 调用的字符串文字转换为 char*(而不是const char*),有时我不会。例如:
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* 的编译器警告。
这是我的问题:
- 让某些函数不采用
const char*是否有优势/原因(和/或为什么 Python API 在这方面不一致)?我的理解是,如果函数可以接受字符串文字,它就不能改变char*所以const修饰符只会加强这一点。我也相信const的区别对于 C(为其编写 API)并不像在 C++ 中那么重要(如果我错了,请纠正我......我的强项是 python,而不是 C/C++)。 Python API 缺乏“const 正确性”是因为它在 C 中根本不那么重要吗? (有一个 2000 年的 old thread on the python mailing list 提出了同样的问题,但它似乎没有去任何地方,这暗示原因可能是由于某些编译器不支持const。由于现在许多函数都有const char*,这似乎不再适用) -
因为我对 C++ 的理解有限,我不确定我是否要正确地转换字符串文字。在我看来,我可以选择以下任何一种(我目前正在做第一种):
// Method 1) Use const_cast<char*> PyImport_ImportFrozenModule(const_cast<char*>("mymodule")); // Method 2) Use (char*) PyImport_ImportFrozenModule((char*) "mymodule"); // Method 3) Use char array char mod[] = "mymodule"; PyImport_ImportFrozenModule(mod);使用哪种方法最好?
更新:
看起来 Python3 分支正在慢慢尝试修复 const 正确性问题。例如,我在上面用作示例的 PyImport_ImportFrozenModule 函数现在在 Python 3.4 中采用 const char*,但仍有一些函数只采用 char*,例如 PyLong_FromString。
【问题讨论】:
-
Here's a thread from 2002 on the python-dev mailing list on this topic。 C API 最初是在没有 const 正确性的情况下创建的,有人想通过在任何地方添加它来解决这个问题。 Guido 拒绝,因为它会破坏第 3 方扩展。
-
Here's another 更新的线程。似乎最初创建 API 时并没有考虑到这一点。多年来,人们一直在某些地方添加它,但并非在所有地方都这样做。
-
@dano 这些是我以前没有找到的很棒的链接!所以听起来只有 C++ 程序员会关心这个(以避免编译器警告),这还不足以尝试修复它。 :(
-
@dano:您应该做出回答,以便我们投票! :)
-
@EthanFurman 当然,我刚刚添加了一个。
标签: python c++ python-c-api