Re: RFC: GProxy, Dynamic Method Invocation



2008/7/2 Tim Janik <timj imendio com>:
> On Tue, 1 Jul 2008, Mikkel Kamstrup Erlandsen wrote:
>
>> Over the past few weeks I have been pondering a way to add dynamic
>> method invocation and introspection to GObjects. I am meaning to
>> implement this myself (unless someone else really want to do it), if
>> the reception is luke-warm or better :-)
>>
>> You can find the draft here:
>> http://live.gnome.org/MikkelKamstrup/GProxyIdea you might want to
>> follow the links to GPlugin there, but that page is still a bit
>> messy...
>>
>> What I would like to discuss is:
>>
>> * Is this utter insanity?
>
> In your emails and on the wiki pages you say (combined):
> - your implementation shouldn't use code generation;
> - you don't want to use libffi to call C methods.
>
> How then, do you actually want to implement dynamic method invocations,
> given that all you can hope to get from GModule is an opaque function
> pointer once a method is found?

I realize that my draft desperately lacks a few examples. Here goes one :-)

I don't want to look up the method pointers in a GModule. The actual
method invocation is implemented inside the GModules. The GModules
only provide a GProxyTransport object which acts as a factory for
Proxies on that transport. So taking a DBus Proxy for example:

/* START EXAMPLE */

GProxyTransport  *transport;
GProxyParams     *params;
GProxy                *proxy;
GMethod              *method;
GValue                 result = {0};

transport = g_proxy_transport_get_transport("dbus");
params = g_proxy_params_new ();

g_proxy_params_set_many (params,
                                          "dbus:name", "org.example.Foo",
                                          "dbus:interface",
"org.example.FooBar",
                                          "dbus:path", "/org/example/foo/main");

/* Store the proxy and method handle and keep them around */
proxy = g_proxy_transport_lookup (tranport, params, NULL, NULL);
method = g_proxy_get_method ("frobnicate");


/* Get ready for a method invocation. Prepare the method params and launch */
invocation = g_method_invocation_new();
g_method_invocation_append_arg (G_TYPE_STRING, "hello proxy!");
g_proxy_invoke (proxy, method, invocation, NULL, &result, NULL);


/* END EXAMPLE */

So, to the explanation. The first call to obtain the transport:

  transport = g_proxy_transport_get_transport("dbus");

scans the installed transport modules, looking for dbus.so and if
found extracts a GProxyTransport instance from it via a special
function defined by the GProxyTransport interface, we could call it
g_proxy_transport_create(void). To obtain the actual proxy we call
into methods that are implemented inside the dbus trasnport GModule:

  proxy = g_proxy_transport_lookup (tranport, params, NULL, NULL);

Behind the scenes this will hook up to the bus and create a dbus proxy
for us. Ie. the dbus module will also instantiate its own subtype og
GProxy to return from g_proxy_transport_lookup().

The proxy method invocation:

  g_proxy_invoke (proxy, method, invocation, NULL, &result, NULL);

Then also just runs down into the private GProxy subclass defined in
the dbus.so GModule. The bottom line is that we only depend on one
well defined symbol from the GModule, namely
g_proxy_transport_create().

I hope this clears it out. Cheers,
Mikkel


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]