用Cython包装包含WxStand的C++类

2024-10-03 06:23:13 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在研究一个Python扩展,以配合使用GUI的WxWiWrdEs编写的C++应用程序。我正在使用Cython,并且让基本的系统(构建工具,加上一个带有适当版本细节的启动扩展等)愉快地工作。在

我只对使后端(非GUI)功能可用感兴趣,比如文件解析和处理。但是,所有类(不仅仅是GUI类)都使用wxString作为字符串数据,例如下面的最小示例:

#include <wx/string.h>

class MyClass{
    wxString name;
    wxString get_name(){
        return this->name;
    }
};

我的问题是包装这样一个类的最好方法是什么?在Python字符串和wxString实例之间有没有一种简单的接口方法?或者我也需要包装wxString类吗?我能不能在某种程度上与wxPython端口连接以避免重新发明轮子?在


Tags: 文件工具方法字符串name功能版本应用程序
2条回答

我尝试的第一种方法是使用wxString构造函数:

wxString(const wxChar* psz, size_t nLength = wxSTRING_MAXLEN)

并将constchar*string传递给它来创建对象。在

然后编写一些内联函数将python字符串转换为wxString,反之亦然。在

^{pr2}$

现在我看到的唯一缺点是,在wxString和python世界中,字符串可能是重复的。在

第二种方法是使用Python的PyString对象字符缓冲区,将wxString子类化并手动重新实现所有操作。Cython可以帮助编写这样的子类。在

我通过使用静态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并根据需要调用函数:

^{pr2}$

相关问题 更多 >