在 Python 中封装 GObject
2007-03-29 12:14:54 来源:WEB开发网static PyObject*
_wrap_egg_tray_icon_send_message(PyGObject *self,
PyObject *args, PyObject *kwargs)
这是 Python-to-C 桥的原型。它由正在对其调用方法的 GObject 的指针、参数数组和关键字参数数组组成。返回值始终是 PyObject* ,因为 Python 中的所有值都是对象(甚至整数)。
{
static char *kwlist[] = {"timeout", "message", NULL};
int timeout, len, ret;
char *message;
该数组定义该函数接受的关键字参数的名称。提供使用关键字参数的能力不是必需的,但它可以使带有许多参数的代码变得清楚许多,而且不需要大量的额外工作。
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
"is#:TrayIcon.send_message", kwlist,
&timeout, &message, &len))
return NULL;
这个复杂的函数调用执行参数解析。我们向它提供所知道的关键字参数以及所有给定参数的列表,它将设置最终参数指向的值。那个看上去费解的字符串声明了所需要的变量类型,我们稍后将说明它。
ret = egg_tray_icon_send_message(EGG_TRAY_ICON(self->obj),
timeout, message, len);
return PyInt_FromLong(ret);
}
这里,我们实际上调用 egg_tray_icon_send_message ,然后将返回的 int 转换成 PyObject 。
起先这看上去有点可怕,但它最初是从 trayicon.c 中的生成代码复制来的。在大多数情况下,如果您只想调优所需要的参数,那么这是完全有可能的。只要从生成的 C 中复制并粘贴相关函数,添加有魔力的覆盖行并编辑该代码,直到它如您所愿。
最重要的更改是修改所需要的参数。 PyArg_ParseTupleAndKeywords 函数中看上去费解的字符串定义了所需要的参数。最初,它是 isi:TrayIcon.send_message ;这意味着参数依次是 int 、 char* (s 表示字符串)和 int ;而且如果抛出一个异常,则该函数称作 TrayIcon.send_message 。我们不想必须在 Python 代码中指定字符串长度,所以将 isi 更改为 is# 。使用 s# 来代替 s 意味着 PyArg_ParseTupleAndKeywords 将自动计算字符串长度并为我们设置另一个变量 — 这正是我们想要的。
要使用新的包装器,只需重新构建共享对象并将测试程序中的 send_message 调用更改成:
t.send_message(1000, message)
如果每件事情都照常进行,那么这个修改后的示例应该有相同的行为,但具有更清晰的代码。
结束游戏
我们采用了小型的但有用的 C GObject,封装它,这样就可以在 Python 中使用它,甚至可以对包装器进行度身定做以符合我们的需要。这里的技术可以多次应用于不同对象,允许您使用在 Python 中找到的任何 GObject。
更多精彩
赞助商链接