2016-01-13 14:35:03 +00:00
|
|
|
|
---
|
|
|
|
|
layout: post
|
|
|
|
|
title: "Emacs: Implement a GObject’s virtual function"
|
2016-02-26 15:26:26 +00:00
|
|
|
|
date: 2016-01-13 13:31:12
|
2016-01-13 14:35:03 +00:00
|
|
|
|
tags: [c, development, emacs]
|
|
|
|
|
published: true
|
|
|
|
|
author:
|
|
|
|
|
name: "Gergely Polonkai"
|
|
|
|
|
email: "gergely@polonkai.eu"
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
I have recently started creating a GLib implementation of the
|
|
|
|
|
Matrix.org API. For that, I have created a GObject interface,
|
|
|
|
|
MatrixAPI, which has as many virtual functions as API calls (which is
|
|
|
|
|
a lot, and expanding). This way I ended up with the following scenario.
|
|
|
|
|
|
|
|
|
|
In `matrix-api.h` I had a struct like this, with a lot more elements:
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
|
void (*initial_sync)(MatrixAPI *api,
|
|
|
|
|
MatrixAPICallback callback,
|
|
|
|
|
gpointer user_data,
|
|
|
|
|
GError **error);
|
|
|
|
|
void (*sync)(MatrixAPI *api,
|
|
|
|
|
MatrixAPICallback callback,
|
|
|
|
|
gpointer user_data,
|
|
|
|
|
GError **error);
|
|
|
|
|
…
|
|
|
|
|
|
|
|
|
|
And in `matrix-http-api.c`, which implements `MatrixAPI`, I have a
|
|
|
|
|
function like this (again, with a lot more elements):
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
matrix_http_api_matrix_api_init(GObjectInterface *iface)
|
|
|
|
|
{
|
|
|
|
|
iface->initial_sync = i_initial_sync;
|
|
|
|
|
iface->sync = i_sync;
|
|
|
|
|
…
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
And every time I wanted to implement a new function from the vtable, I
|
|
|
|
|
had to copy the prototype, and add an `iface->foo_bar = i_foo_bar`
|
|
|
|
|
line and an actual function header for `i_foo_bar` with the same
|
|
|
|
|
parameters. That’s a cumbersome job for more than 40 function
|
|
|
|
|
headers. But emacs comes to the rescue!
|
|
|
|
|
|
2017-08-31 09:55:54 +00:00
|
|
|
|
{% gist bfd36be8b515edced3d2 implement-gobject-vfunc.el %}
|
2016-01-13 14:35:03 +00:00
|
|
|
|
|
|
|
|
|
Now all I have to do is to copy the whole vtable entry into
|
|
|
|
|
`matrix_http_api_matrix_api_init()`, execute `M-x
|
|
|
|
|
implement-gobject-vfunc`, then put the same vtable entry somewhere
|
|
|
|
|
before the interface init function, and execute `M-x
|
2016-02-26 15:19:42 +00:00
|
|
|
|
implement-gobject-vfunc-prototype`.
|