OpenSource

[gdbus] method 등록 및 호출

Roien 2018. 3. 18.
반응형


gdbus call

1) registration

a. generate gdbus wrapping code

ex.  com.test.module1.xml
<node>
<interface name="com.test.module1">
<method name="HelloWorld">
<arg name="greeting" direction="in" type="s"/>
<arg name="response" direction="out" type="s"/>
</method>
</interface>
</node>

gdbus-codegen --generate-c-code testbus --c-namespace TestBus --interface-prefix com.test. com.test.module1.xml
-> testbus.c/h


b. build
FLAGS=$(shell pkg-config --libs --cflags gio-2.0 gio-unix-2.0 glib-2.0)

server: server.o testbus.o
gcc -o $@ $^ $(FLAGS)

client: client.o testbus.o
gcc -o $@ $^ $(FLAGS)
gcc -o testbus server.c testbus.c `pkg-config --libs --cflags gio-2.0 gio-unix-2.0 glib-2.0`
gcc -o testbus client.c testbus.c `pkg-config --libs --cflags gio-2.0 gio-unix-2.0 glib-2.0`



c. server side registration

static gboolean
on_handle_hello_world (TestBusModule1 *interface, GDBusMethodInvocation *invocation,
const gchar *greeting, gpointer user_data) {
gchar *response = g_strdup_printf ("Hello world %s!!.", greeting);
test_bus_module1_complete_hello_world(interface, invocation, response);
g_print("[%04u]%s: resp: %s\n", __LINE__, _MODULE_, response);
g_free(response);
return TRUE;
}

static void
on_name_acquired(GDBusConnection *connection, const gchar *name, gpointer user_data) {
GError *error = NULL;
TestBusModule1 *interface = (TestBusModule1 *)test_bus_module1_skeleton_new();
g_signal_connect(interface, "handle-hello-world", G_CALLBACK (on_handle_hello_world), NULL);
!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (interface), connection, "/com/test/module1", &error);
}

g_bus_own_name(G_BUS_TYPE_SESSION, "com.test", G_BUS_NAME_OWNER_FLAGS_NONE, NULL,
on_name_acquired, NULL, NULL, NULL);

to unexport the object

 - g_bus_own_name에서 bus name 등록 시, on_name_acquired가 호출됨
 - bus name 등록 시 (on_name_acquired), method가 호출 될 수 있도록 다음과 같이 등록
 
"handle-hello-world"로 callback 등록
g_signal_connect(interface, "handle-hello-world", G_CALLBACK (on_handle_hello_world), NULL);
XML 내 "HelloWorld" method의 코드 생성 시, 다음과 같이 HelloWorld와 handle-hello-world를 연결
static const _ExtendedGDBusMethodInfo _test_bus_module1_method_info_hello_world =
...
(gchar *) "HelloWorld",
"handle-hello-world",
...


2) call

다음과 같이 proxy 획득 

TestBusModule1 *proxy = test_bus_module1_proxy_new_for_bus_sync(
G_BUS_TYPE_SESSION, 
G_DBUS_PROXY_FLAGS_NONE,
"com.test", 
"/com/test/module1", 
NULL, 
&error);

test_bus_module1_proxy_new_for_bus_sync는 다음을 수행하는 wrapper

GInitable *ret = g_initable_new (TEST_BUS_TYPE_MODULE1_PROXY, 
cancellable, error, "g-flags", flags, "g-name", name, 
"g-bus-type", bus_type, "g-object-path", object_path, 
"g-interface-name", "com.test.module1", NULL);

hello world 호출 (async)
test_bus_module1_call_hello_world_sync(proxy, "test", &buf, NULL, &error);
g_dbus_proxy_call_sync (G_DBUS_PROXY (proxy),
"HelloWorld",
g_variant_new ("(s)", arg_greeting), 
G_DBUS_CALL_FLAGS_NONE,
-1,
cancellable,
error);

g_dbus_proxy_call_sync_internal 를 호출하고, 
interface에서 method 검색 후,
expected_method_info = lookup_method_info (proxy, target_method_name);
호출
g_dbus_connection_call_with_unix_fd_list_sync(..., target_method_name, ...)
g_dbus_connection_call_sync_internal
or
g_dbus_connection_call_sync(..., target_method_name, ...)
g_dbus_connection_call_sync_internal
둘 다, 
g_dbus_connection_call_sync_internal를 호출하며, 
이는 g_dbus_message_new_method_call(bus_name, object_path, interface_name, method_name);를 호출
즉, 기존 dbus call을 사용


반응형

댓글