csizeof.add_argument (new CCodeIdentifier (get_ccode_name (array_type.element_type)));
in_arg_map.set (get_param_pos (0.1), csizeof);
} else if (m is DynamicMethod) {
+ emit_context.push_symbol (m);
m.clear_parameters ();
int param_nr = 1;
foreach (Expression arg in expr.get_argument_list ()) {
param.accept (this);
}
generate_dynamic_method_wrapper ((DynamicMethod) m);
+ emit_context.pop_symbol ();
} else if (m is CreationMethod && context.profile == Profile.GOBJECT && m.parent_symbol is Class) {
ccode.add_assignment (get_this_cexpression (), new CCodeCastExpression (ccall, get_ccode_name (current_class) + "*"));
ccode.add_expression (destroy_value (unary.inner.target_value));
}
+ // infer type of out-parameter from argument
+ if (ma.symbol_reference is DynamicMethod && unary.target_value.value_type == null) {
+ unary.target_value.value_type = unary.inner.value_type.copy ();
+ }
+
// assign new value
store_value (unary.inner.target_value, transform_value (unary.target_value, unary.inner.value_type, arg), expr.source_reference);
}
public override void generate_dynamic_method_wrapper (DynamicMethod method) {
- var dynamic_method = (DynamicMethod) method;
-
var func = new CCodeFunction (get_ccode_name (method));
func.modifiers = CCodeModifiers.STATIC;
push_function (func);
- if (dynamic_method.dynamic_type.data_type == dbus_proxy_type) {
+ if (method.dynamic_type.data_type == dbus_proxy_type) {
generate_marshalling (method, CallType.SYNC, null, method.name, -1);
} else {
- Report.error (method.source_reference, "dynamic methods are not supported for `%s'".printf (dynamic_method.dynamic_type.to_string ()));
+ Report.error (method.source_reference, "dynamic methods are not supported for `%s'".printf (method.dynamic_type.to_string ()));
}
pop_function ();
dbus/errors.test \
dbus/async.test \
dbus/async-errors.test \
+ dbus/dynamic-method.test \
dbus/enum-string-marshalling.vala \
dbus/signals.test \
dbus/filedescriptor.test \
--- /dev/null
+Packages: gio-2.0
+D-Bus
+
+Program: client
+
+async void run () {
+ try {
+ var bus = yield Bus.@get (BusType.SESSION);
+ dynamic DBusProxy test = yield new DBusProxy (bus, DBusProxyFlags.NONE, null, bus.get_unique_name (), "/org/example/test", "org.example.Test");
+ string s;
+ int i = test.do_foo (42, out s);
+ assert (i == 23);
+ assert (s == "foo");
+ } catch {
+ }
+
+ main_loop.quit ();
+}
+
+MainLoop main_loop;
+
+void main () {
+ main_loop = new MainLoop ();
+ run.begin ();
+ main_loop.run ();
+}
+
+Program: server
+
+[DBus (name = "org.example.Test")]
+class Test : Object {
+ public int do_foo (int i, out string s) throws Error {
+ assert (i == 42);
+ s = "foo";
+ return 23;
+ }
+}
+
+MainLoop main_loop;
+
+void client_exit (Pid pid, int status) {
+ // client finished, terminate server
+ assert (status == 0);
+ main_loop.quit ();
+}
+
+void main () {
+ var conn = Bus.get_sync (BusType.SESSION);
+ conn.register_object ("/org/example/test", new Test ());
+
+ // try to register service in session bus
+ var request_result = conn.call_sync ("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "RequestName",
+ new Variant ("(su)", "org.example.Test", 0x4), null, 0, -1);
+ assert ((uint) request_result.get_child_value (0) == 1);
+
+ // server ready, spawn client
+ Pid client_pid;
+ Process.spawn_async (null, { "dbus_dynamic_method_client" }, null, SpawnFlags.DO_NOT_REAP_CHILD, null, out client_pid);
+ ChildWatch.add (client_pid, client_exit);
+
+ main_loop = new MainLoop ();
+ main_loop.run ();
+}
m.add_error_type (err);
m.access = SymbolAccessibility.PUBLIC;
m.add_parameter (new Parameter.with_ellipsis ());
+ m.this_parameter = new Parameter ("this", dynamic_object_type.copy ());
dynamic_object_type.type_symbol.scope.add (null, m);
symbol_reference = m;
}