我正在开发一个Python扩展,以配合使用wxWidgets为GUI编写的C ++应用程序。我正在使用Cython,并且拥有基本系统(构建工具,以及具有适当版本细节的入门扩展等),并且正在愉快地工作。
我只对提供后端(非GUI)功能感兴趣,例如文件解析和处理。但是,所有类 - 不仅仅是GUI类 - 都使用wxString
作为字符串数据,例如以下最小例子:
#include <wx/string.h>
class MyClass{
wxString name;
wxString get_name(){
return this->name;
}
};
我的问题是包装这样一个课程的最佳方法是什么?是否有一种简单的方法来连接Python字符串和wxString
实例?或者我还需要包装wxString
类吗?我是否能够以某种方式与wxPython端口绑定以避免重新发明轮子?
答案 0 :(得分:2)
我通过使用静态wxString::FromUTF8()
函数将Python转换为wxString,并将wxString.ToUTF8()
转换为另一个方向来实现它。以下是我提出的代码:
# Import the parts of wxString we want to use.
cdef extern from "wx/string.h":
cdef cppclass wxString:
char* ToUTF8()
# Import useful static functions from the class.
cdef extern from "wx/string.h" namespace "wxString":
wxString FromUTF8(char*)
# Function to convert from Python string to wxString. This can be given either
# a unicode string, or a UTF-8 encoded byte string. Results with other encodings
# are undefined and will probably lead to errors.
cdef inline wxString from_python(python_string):
# If it is a Python unicode string, encode it to a UTF-8 byte string as this
# is how we will pass it to wxString.
if isinstance(python_string, unicode):
byte_string = python_string.encode('UTF-8')
# It is already a byte string, and we have no choice but to assume its valid
# UTF-8 as theres no (sane/efficient) way to detect the encoding.
else:
byte_string = python_string
# Turn the byte string (which is still a Python object) into a C-level char*
# string.
cdef char* c_string = byte_string
# Use the static wxString::FromUTF8() function to get us a wxString.
return FromUTF8(c_string)
# Function to convert a wxString to a UTF-8 encoded Python byte string.
cdef inline object to_python_utf8(wxString wx_string):
return wx_string.ToUTF8()
# Function to convert a wxString to a Python unicode string.
cdef inline object to_python_unicode(wxString wx_string):
# Since the wxString.ToUTF8() method returns a const char*, we'd have to try
# and cast it if we wanted to do it all in here. I've tried this and can't
# seem to get it to work. But calling the to_python_utf8() function
# means Cython handles the conversions and it all just works. Plus, since
# they are defined as inline functions this may well be simplified down when
# compiled.
byte_string = to_python_utf8(wx_string)
# Decode it to a unicode string and we're done.
return byte_string.decode('UTF-8')
只需将其放在.pxd文件中(个人而言,我将其放在wx/string.pxd
的子目录中 - 如果您选择执行相同的操作,请确保创建wx/__init__.pdx
。然后cimport
它并根据需要调用函数:
cimport wx.string
wx_string = wx.string.from_python(python_string)
python_string = wx.string.to_python_unicode(wx_string)
答案 1 :(得分:0)
我尝试的第一种方法是使用wxString构造函数:
wxString(const wxChar* psz, size_t nLength = wxSTRING_MAXLEN)
并将const char *字符串传递给它以创建对象。
然后编写一些内联函数,从python字符串转换为wxString,反之亦然。
PyObject* PyString_FromStringAndSize(const char *v, Py_ssize_t len)
现在我唯一看到的缺点是字符串可能在wxString和python世界中重复。
第二种方法是将WxString子类化,并以使用Python的PyString Object字符缓冲区的方式手动重新实现所有操作。 Cython可以帮助编写这样的子类。