将Python 3 Unicode转换为std::string的干净方法
Clean Way to Convert Python 3 Unicode to std::string
我使用Python 2 API包装了很多C++(由于各种技术原因,我不能使用swig或boost.Python之类的东西)。当我必须将一个字符串(通常是一个路径,总是ASCII)传递到C/C++中时,我会使用这样的东西:
std::string file_name = PyString_AsString(py_file_name);
if (PyErr_Occurred()) return NULL;
现在我正在考虑更新到Python3,其中不存在PyString_*
方法。我找到了一个解决方案,说我应该做这样的事情:
PyObject* bytes = PyUnicode_AsUTF8String(py_file_name);
std::string file_name = PyBytes_AsString(bytes);
if (PyErr_Occurred()) return NULL;
Py_DECREF(bytes);
然而,这是两倍多的行,看起来有点难看(更不用说如果我忘记了最后一行,它可能会导致内存泄漏)。
另一种选择是重新定义python函数来操作bytes
对象,并像下面的一样调用它们
def some_function(path_name):
_some_function(path_name.encode('utf8'))
这并不可怕,但它确实需要为每个函数提供一个python端包装器。
有没有更干净的方法来处理这个问题?
看起来该解决方案存在于带有char* PyUnicode_AsUTF8(PyObject* unicode)
的python 3.3中。这应该与python 2中的PyString_AsString()
函数完全相同。
如果你知道(当然,你可以用断言或类似的方法检查)它都是ASCII,那么你可以简单地创建它:
std::string py_string_to_std_string(PyUnicode_string py_file_name)
{
len = length of py_file_name; // Not sure how you write that in python.
std::string str(len);
for(int i = 0; i < len; i++)
str += py_file_name[i];
return str;
}
提供接受答案的改进版本,而不是使用PyUnicode_AsUTF8(...)
更好地使用PyUnicode_AsUTF8AndSize(…)。
因为字符串可能在中间的某个位置包含空字符(0代码点),所以如果使用PyUnicode_AsUTF8(...)
,则生成的std::string
将包含完整字符串的截断版本。
Py_ssize_t size = 0;
char const * pc = PyUnicode_AsUTF8AndSize(obj, &size);
std::string s;
if (pc)
s = std::string(pc, size);
else
// Error, handle!
相关文章:
- 将(临时的?)std::string传递给使用它来构造一个接受副本的对象的函数的最佳方法是什么?
- 如果子类中没有构造函数方法,则错误"no matching function for call to 'LGame::LGame(String&)'"
- Arduino trim() 和 replace() 方法返回从 'void' 到非标量类型'String'请求的转换
- 从类方法返回 "const char*" 作为 std::string&
- 将空填充但不以空结尾的固定长度字符数组转换为 std::string 的最佳方法
- 自动将 std::string 转换为 char* 而无需每次都调用 c_str() 的最佳方法
- 在 Extern "C" 中将 List<String^> 返回到 Vector<std::string> 的正确方法?
- C++ std::string 中是否有任何函数可以计算两个字符串的相同起始字符的总数或任何最佳方法
- std::copy with return values - 防止"expression: string iterators incompatible"的更好方法?
- 如何从JSON String创建工厂方法
- 如何在我的源代码中找到所有发生的情况,其中std :: string被传递给方法作为副本而不是恒定引用
- 为什么在类构造函数方法中,std::string 参数在调试时显示不同的结果?
- 如何让一种方法采用 vector&&<string>&而不是 vector<string>?
- boost-python 当C++方法返回 std::map<string,X*>
- 链接webrtc本机时出错,因为未定义对具有std::string的方法的引用
- 如何为 Product* getProductFromID(std::string)编写方法定义;.
- 用一个字符制作 std::string 的最佳方法是什么?
- C++ 字符串 - 如何为 wstring 实现此'IsEmptyOrSpace(string)'方法?
- 为什么我不能从 const String& 方法返回 NULL?
- 为什么std::string方法的风格与STL的其他部分不同?