2010-09-19 37 views
6

Tôi đang làm việc với một mô đun hiện có tại thời điểm cung cấp giao diện C++ và thực hiện một số thao tác với chuỗi.Python: Chuyển chuỗi unicode sang mô-đun C++

tôi cần phải sử dụng chuỗi Unicode và các mô-đun tiếc là đã không có bất kỳ sự hỗ trợ cho một giao diện Unicode, vì vậy tôi đã viết một chức năng phụ thêm vào giao diện:

void SomeUnicodeFunction(const wchar_t* string) 

Tuy nhiên, khi tôi cố gắng để sử dụng đoạn mã sau bằng Python:

SomeModule.SomeUnicodeFunction(ctypes.c_wchar_p(unicode_string)) 

tôi nhận được lỗi này:

ArgumentError: Python argument types in 
    SomeModule.SomeUnicodeFunction(SomeModule, c_wchar_p) 
did not match C++ signature: 
    SomeUnicodeFunction(... {lvalue}, wchar_t const*) 

(tên đã được thay đổi).

Tôi đã thử thay đổi wchar_t trong mô-đun C++ thành Py_UNICODE mà không thành công. Làm thế nào để giải quyết vấn đề này?

+0

Boost.python không tự động nhận dạng các loại ctypes, theo như tôi biết, nhưng có lẽ nó chỉ hoạt động với các chuỗi unicode tích hợp. Điều gì sẽ xảy ra nếu bạn cố gắng gọi 'SomeModule.SomeUnicodeFunction (unicode_string)'? – Doug

+0

@Dough: cùng một lỗi, nhưng với "unicode" thay vì "c_wchar_p" làm loại đối số Python. –

+0

@Matthew, w/hoặc w/o 'c_wchar_p' cast, có vẻ như nó _should_ làm việc ngoại trừ có thể cho' const' (không được đề cập trong tài liệu 'ctypes'') - điều gì sẽ xảy ra nếu bạn bỏ qua ' const' trong mã C? (Lưu ý không có hỗ trợ C++ trực tiếp trong 'ctypes': hàm phải là' extern C' từ quan điểm của C++, tất nhiên). –

Trả lời

2

Đối với Linux bạn không cần phải thay đổi API của bạn, chỉ cần làm:

SomeModule.SomeFunction(str(s.encode('utf-8'))) 

Trên Windows tất cả các API Unicode đang sử dụng UTF-16 LE (Little Endian) vì vậy bạn phải mã hóa nó theo cách này:

SomeModule.SomeFunctionW(str(s.encode('utf-16-le'))) 

Thông tin cần biết: wchar_t thể có kích thước khác nhau trên các nền tảng khác nhau: 8, 16 hoặc 32 bit.

+0

Tôi đang sử dụng Linux, thực sự. Tôi đã cập nhật câu trả lời của riêng mình cho câu hỏi. –

2

Tìm thấy một hack để làm việc xung quanh vấn đề này:

SomeModule.SomeUnicodeFunction(str(s.encode('utf-8'))) 

Có vẻ như là làm việc tốt cho các mục đích của tôi cho đến nay.

Cập nhật: Thực ra, sử dụng UTF-8 có nghĩa là tôi tránh bất kỳ nhu cầu nào đối với SomeUnicodeFunction và có thể sử dụng chức năng SomeFunction tiêu chuẩn mà không cần dùng unicode. Tìm hiểu điều gì đó mới mỗi ngày tôi đoán :).

Các vấn đề liên quan