2013-07-07 30 views
6

Tôi bọc rất nhiều C++ bằng cách sử dụng API Python 2 (Tôi không thể sử dụng những thứ như swig hoặc boost.python vì các lý do kỹ thuật khác nhau). Khi tôi phải vượt qua một chuỗi (thường là một con đường, luôn ASCII) vào C/C++, tôi sử dụng một cái gì đó như thế này:Cách sạch để chuyển đổi Python 3 Unicode thành std :: string

std::string file_name = PyString_AsString(py_file_name); 
if (PyErr_Occurred()) return NULL; 

Bây giờ tôi đang xem xét cập nhật lên Python 3, nơi PyString_* phương pháp này không tồn tại . Tôi thấy one solution nói rằng tôi nên làm điều gì đó như thế này:

PyObject* bytes = PyUnicode_AsUTF8String(py_file_name); 
std::string file_name = PyBytes_AsString(bytes); 
if (PyErr_Occurred()) return NULL; 
Py_DECREF(bytes); 

Tuy nhiên đây là gấp đôi so với nhiều dòng và có vẻ hơi xấu xí (chưa kể rằng nó có thể giới thiệu một rò rỉ bộ nhớ nếu tôi quên dòng cuối cùng).

Các tùy chọn khác là để xác định lại chức năng python để hoạt động trên bytes đối tượng, và gọi họ là như thế này

def some_function(path_name): 
    _some_function(path_name.encode('utf8')) 

Đây không phải là khủng khiếp, nhưng nó đòi hỏi một wrapper python-side cho mỗi chức năng .

Có cách nào sạch hơn để giải quyết vấn đề này không?

+0

Tại sao không 'std :: wstring'? –

+0

Hmm, tại sao tôi sẽ sử dụng 'std :: wstring'? Tôi đang làm việc độc quyền với Linux, vì vậy khi tôi hiểu nó, tôi có lẽ không cần một 'wstring' cho bất cứ điều gì. – Shep

+2

Tại sao không chỉ quấn nó trong chức năng riêng của bạn mà chuyển đổi 'PyObject' thành' std :: string'? 'std :: string convertPyString (PyObject * pyString);' –

Trả lời

1

Nếu bạn biết (và dĩ nhiên, bạn có thể kiểm tra với một khẳng định hoặc tương tự) rằng đó là tất cả ASCII, sau đó bạn chỉ có thể tạo ra nó như thế này:

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; 
} 
Các vấn đề liên quan