I have written my application to mostly using g_dbus_connection_call_sync() after an InterfacesAdded occurs on org.freedesktop.DBus.ObjectManager.
There is also a g_dbus_proxy_call_sync() which I have not tried to use.
In my program I start with g_dbus_get_sync() which creates a D-Bus connection. Then I call g_dbus_connection_signal_subscribe() which does a callback when the interface I am interested in gets created.
Why would I want to do the extra step of creating the proxy?
The D-BUS Tutorial says:
A proxy object is a convenient native object created to represent a remote object in another process. The low-level DBus API involves manually creating a method call message, sending it, then manually receiving and processing the method reply message. Higher-level bindings provide proxies as an alternative. Proxies look like a normal native object; but when you invoke a method on the proxy object, the binding converts it into a DBus method call message, waits for the reply message, unpacks the return value, and returns it from the native method.
Then they show pseudo code that is somewhat more involved in the non-proxy method, but using g_dbus*() functions, I am not sure that this is the case.