dbus/mono Arguments.cs, NONE, 1.1 Bus.cs, NONE, 1.1 Custom.cs, NONE,
1.1 DBusException.cs, NONE, 1.1 Handler.cs, NONE,
1.1 InterfaceAttribute.cs, NONE, 1.1 Introspector.cs, NONE,
1.1 MethodAttribute.cs, NONE, 1.1 MethodCall.cs, NONE,
1.1 MethodReturn.cs, NONE, 1.1 ProxyBuilder.cs, NONE,
1.1 README, NONE, 1.1 Server.cs, NONE, 1.1 Service.cs, NONE,
1.1 Signal.cs, NONE, 1.1 TODO, NONE, 1.1 Connection.cs, 1.4,
1.5 Error.cs, 1.2, 1.3 Makefile.am, 1.2, 1.3 Message.cs, 1.5,
1.6 Test.cs, 1.4, 1.5 DBus.cs, 1.4, NONE
Owen Fraser-Green
ow3n at pdx.freedesktop.org
Tue Mar 23 04:10:34 PST 2004
- Previous message: dbus dbus-sharp.pc.in, NONE, 1.1 ChangeLog, 1.461, 1.462 Makefile.am,
1.18, 1.19 configure.in, 1.78, 1.79
- Next message: dbus configure.in,1.79,1.80
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /cvs/dbus/dbus/mono
In directory pdx:/tmp/cvs-serv17190/mono
Modified Files:
Connection.cs Error.cs Makefile.am Message.cs Test.cs
Added Files:
Arguments.cs Bus.cs Custom.cs DBusException.cs Handler.cs
InterfaceAttribute.cs Introspector.cs MethodAttribute.cs
MethodCall.cs MethodReturn.cs ProxyBuilder.cs README Server.cs
Service.cs Signal.cs TODO
Removed Files:
DBus.cs
Log Message:
First checkin of the Mono bindings.
--- NEW FILE: Arguments.cs ---
using System;
using System.Collections;
using System.Reflection;
using System.Runtime.InteropServices;
namespace DBus
{
// Holds the arguments of a message. Provides methods for appending
// arguments and to assist in matching .NET types with D-BUS types.
public class Arguments : IEnumerable
{
// Must follow sizeof(DBusMessageIter)
internal const int DBusMessageIterSize = 14*4;
private static Hashtable dbusTypes = null;
private Message message;
private IntPtr appenderIter = Marshal.AllocCoTaskMem(DBusMessageIterSize);
private IEnumerator enumerator = null;
internal Arguments()
{
}
~Arguments()
{
Marshal.FreeCoTaskMem(appenderIter);
}
internal Arguments(Message message)
{
this.message = message;
}
// Checks the suitability of a D-BUS type for supporting a .NET
// type.
public static bool Suits(Type dbusType, Type type)
{
object [] pars = new object[1];
pars[0] = type;
return (bool) dbusType.InvokeMember("Suits", BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod, null, null, pars, null);
}
// Find a suitable match for the given .NET type or throw an
// exception if one can't be found.
public static Type MatchType(Type type)
{
foreach(Type dbusType in DBusTypes.Values) {
if (Suits(dbusType, type)) {
return dbusType;
}
}
throw new ApplicationException("No suitable DBUS type found for type '" + type + "'");
}
// The D-BUS types.
public static Hashtable DBusTypes {
get
{
if (dbusTypes == null) {
dbusTypes = new Hashtable();
foreach (Type type in Assembly.GetAssembly(typeof(DBusType.IDBusType)).GetTypes()) {
if (type != typeof(DBusType.IDBusType) && typeof(DBusType.IDBusType).IsAssignableFrom(type)) {
dbusTypes.Add(GetCode(type), type);
}
}
}
return dbusTypes;
}
}
// Append an argument
public void Append(DBusType.IDBusType dbusType)
{
if (dbusType.GetType() == typeof(DBusType.ObjectPath)) {
((DBusType.ObjectPath) dbusType).SetService(message.Service);
}
dbusType.Append(appenderIter);
}
// Append an argument of the specified type
private void AppendType(Type type, object val)
{
object [] pars = new Object[1];
pars[0] = val;
DBusType.IDBusType dbusType = (DBusType.IDBusType) Activator.CreateInstance(MatchType(type), pars);
Append(dbusType);
}
// Append the results of a method call
public void AppendResults(MethodInfo method, object retVal, object [] parameters)
{
InitAppending();
if (method.ReturnType != typeof(void)) {
AppendType(method.ReturnType, retVal);
}
for (int i = 0; i < method.GetParameters().Length; i++) {
ParameterInfo par = method.GetParameters()[i];
if (par.IsOut || par.ParameterType.ToString().EndsWith("&")) {
// It's an OUT or INOUT parameter.
AppendType(par.ParameterType.UnderlyingSystemType, parameters[i]);
}
}
}
// Get the parameters
public object[] GetParameters(MethodInfo method)
{
ParameterInfo[] pars = method.GetParameters();
ArrayList paramList = new ArrayList();
enumerator = GetEnumerator();
foreach (ParameterInfo par in pars) {
if (!par.IsOut) {
// It's an IN or INOUT paramter.
enumerator.MoveNext();
DBusType.IDBusType dbusType = (DBusType.IDBusType) enumerator.Current;
paramList.Add(dbusType.Get(par.ParameterType));
} else {
// It's an OUT so just create a parameter for it
object var = null;
paramList.Add(var);
}
}
return paramList.ToArray();
}
// Parse the IN & REF parameters to a method and return the types in a list.
public static object[] ParseInParameters(MethodInfo method)
{
ArrayList types = new ArrayList();
ParameterInfo[] pars = method.GetParameters();
foreach (ParameterInfo par in pars) {
if (!par.IsOut) {
types.Add(MatchType(par.ParameterType));
}
}
return types.ToArray();
}
// Parse the OUT & REF parameters to a method and return the types in a list.
public static object[] ParseOutParameters(MethodInfo method)
{
ArrayList types = new ArrayList();
ParameterInfo[] pars = method.GetParameters();
foreach (ParameterInfo par in pars) {
if (par.IsOut || par.ParameterType.ToString().EndsWith("&")) {
types.Add(MatchType(par.ParameterType));
}
}
return types.ToArray();
}
// Get the appropriate constructor for a D-BUS type
public static ConstructorInfo GetDBusTypeConstructor(Type dbusType, Type type)
{
ConstructorInfo constructor = dbusType.GetConstructor(new Type[] {type.UnderlyingSystemType});
if (constructor == null)
throw new ArgumentException("There is no valid constructor for '" + dbusType + "' from type '" + type + "'");
return constructor;
}
// Get the signature of a method
public static string ParseParameters(MethodInfo method)
{
ParameterInfo[] pars = method.GetParameters();
string key = "";
foreach (ParameterInfo par in pars) {
if (!par.IsOut) {
Type dbusType = MatchType(par.ParameterType);
key += GetCode(dbusType);
}
}
return key;
}
// Get the type code for a given D-BUS type
public static char GetCode(Type dbusType)
{
return (char) dbusType.InvokeMember("Code", BindingFlags.Static | BindingFlags.GetField, null, null, null);
}
// Get a complete method signature
public override string ToString()
{
IntPtr iter = Marshal.AllocCoTaskMem(DBusMessageIterSize);
string key = "";
// Iterate through the parameters getting the type codes to a string
dbus_message_iter_init(message.RawMessage, iter);
do {
char code = (char) dbus_message_iter_get_arg_type(iter);
if (code == '\0')
return key;
key += code;
} while (dbus_message_iter_next(iter));
Marshal.FreeCoTaskMem(iter);
return key;
}
// Move to the next parameter
public DBusType.IDBusType GetNext()
{
enumerator.MoveNext();
return (DBusType.IDBusType) enumerator.Current;
}
// Begin appending
public void InitAppending()
{
dbus_message_append_iter_init(message.RawMessage, appenderIter);
}
// Get the enumerator
public IEnumerator GetEnumerator()
{
return new ArgumentsEnumerator(this);
}
private class ArgumentsEnumerator : IEnumerator
{
private Arguments arguments;
private bool started = false;
private IntPtr iter = Marshal.AllocCoTaskMem(Arguments.DBusMessageIterSize);
public ArgumentsEnumerator(Arguments arguments)
{
this.arguments = arguments;
Reset();
}
~ArgumentsEnumerator()
{
Marshal.FreeCoTaskMem(iter);
}
public bool MoveNext()
{
if (started) {
return dbus_message_iter_next(iter);
} else {
started = true;
return true;
}
}
public void Reset()
{
dbus_message_iter_init(arguments.message.RawMessage, iter);
started = false;
}
public object Current
{
get
{
object [] pars = new Object[1];
pars[0] = iter;
Type type = (Type) DBusTypes[(char) dbus_message_iter_get_arg_type(iter)];
DBusType.IDBusType dbusType = (DBusType.IDBusType) Activator.CreateInstance(type, pars);
// Special case for ObjectPath
if (type == typeof(DBusType.ObjectPath)) {
((DBusType.ObjectPath) dbusType).SetService(arguments.message.Service);
}
return dbusType;
}
}
}
[DllImport("dbus-1")]
private extern static void dbus_message_append_iter_init(IntPtr rawMessage, IntPtr iter);
[DllImport("dbus-1")]
private extern static bool dbus_message_iter_has_next(IntPtr iter);
[DllImport("dbus-1")]
private extern static bool dbus_message_iter_next(IntPtr iter);
[DllImport("dbus-1")]
private extern static void dbus_message_iter_init(IntPtr rawMessage, IntPtr iter);
[DllImport("dbus-1")]
private extern static int dbus_message_iter_get_arg_type(IntPtr iter);
}
}
--- NEW FILE: Bus.cs ---
namespace DBus
{
using System;
using System.Runtime.InteropServices;
using System.Diagnostics;
public class Bus
{
// Keep in sync with C
private enum BusType
{
Session = 0,
System = 1,
Activation = 2
}
public static Connection GetSessionBus()
{
return GetBus(BusType.Session);
}
public static Connection GetSystemBus()
{
return GetBus(BusType.System);
}
private static Connection GetBus(BusType busType)
{
Error error = new Error();
error.Init();
IntPtr rawConnection = dbus_bus_get((int) busType, ref error);
if (rawConnection != IntPtr.Zero) {
Connection connection = Connection.Wrap(rawConnection);
connection.SetupWithMain();
dbus_connection_unref(rawConnection);
return connection;
} else {
throw new DBusException(error);
}
}
[DllImport ("dbus-1")]
private extern static IntPtr dbus_bus_get (int which, ref Error error);
[DllImport ("dbus-1")]
private extern static void dbus_connection_unref (IntPtr ptr);
}
}
--- NEW FILE: Custom.cs ---
using System;
using DBus;
namespace DBus
{
public struct Custom
{
public string Name;
public byte[] Data;
public Custom(string name, byte[] data)
{
Name = name;
Data = data;
}
}
}
--- NEW FILE: DBusException.cs ---
namespace DBus
{
using System;
using System.Runtime.InteropServices;
public class DBusException : ApplicationException
{
internal DBusException (Error error) : base (error.Message) {
error.Free();
}
}
}
--- NEW FILE: Handler.cs ---
namespace DBus
{
using System;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Reflection;
using System.Collections;
internal class Handler
{
private string[] path = null;
private string pathName = null;
private Introspector introspector = null;
private object handledObject = null;
private Hashtable handledMethods = null;
private DBusObjectPathVTable vTable;
private Connection connection;
private Service service;
private DBusHandleMessageFunction filterCalled;
internal delegate void DBusObjectPathUnregisterFunction(IntPtr rawConnection,
IntPtr userData);
internal delegate int DBusObjectPathMessageFunction(IntPtr rawConnection,
IntPtr rawMessage,
IntPtr userData);
internal delegate int DBusHandleMessageFunction(IntPtr rawConnection,
IntPtr rawMessage,
IntPtr userData);
private enum Result
{
Handled = 0,
NotYetHandled = 1,
NeedMemory = 2
}
[StructLayout (LayoutKind.Sequential)]
private struct DBusObjectPathVTable
{
public DBusObjectPathUnregisterFunction unregisterFunction;
public DBusObjectPathMessageFunction messageFunction;
public IntPtr padding1;
public IntPtr padding2;
public IntPtr padding3;
public IntPtr padding4;
public DBusObjectPathVTable(DBusObjectPathUnregisterFunction unregisterFunction,
DBusObjectPathMessageFunction messageFunction)
{
this.unregisterFunction = unregisterFunction;
this.messageFunction = messageFunction;
this.padding1 = IntPtr.Zero;
this.padding2 = IntPtr.Zero;
this.padding3 = IntPtr.Zero;
this.padding4 = IntPtr.Zero;
}
}
~Handler()
{
if (Connection != null && Connection.RawConnection != IntPtr.Zero && path != null) {
dbus_connection_unregister_object_path(Connection.RawConnection,
Path);
}
}
public Handler(object handledObject,
string pathName,
Service service)
{
Service = service;
Connection = service.Connection;
HandledObject = handledObject;
// Strip the leading / off if there is one and get the path as an array
pathName = pathName.TrimStart('/');
this.path = pathName.Split('/');
this.pathName = "/" + pathName;
// Create the vTable and register the path
vTable = new DBusObjectPathVTable(new DBusObjectPathUnregisterFunction(Unregister_Called),
new DBusObjectPathMessageFunction(Message_Called));
if (!dbus_connection_register_object_path(Connection.RawConnection,
Path,
ref vTable,
IntPtr.Zero))
throw new OutOfMemoryException();
// Setup the filter function
this.filterCalled = new DBusHandleMessageFunction(Filter_Called);
if (!dbus_connection_add_filter(Connection.RawConnection,
this.filterCalled,
IntPtr.Zero,
IntPtr.Zero))
throw new OutOfMemoryException();
}
private void RegisterMethod(MethodInfo method)
{
string key = method.Name + " " + Arguments.ParseParameters(method);
handledMethods.Add(key, method);
}
public object HandledObject
{
get
{
return this.handledObject;
}
set
{
this.handledObject = value;
object[] attributes;
// Register the methods
this.handledMethods = new Hashtable();
this.introspector = new Introspector(value.GetType());
foreach (MethodInfo method in this.introspector.Methods) {
RegisterMethod(method);
}
}
}
public int Filter_Called(IntPtr rawConnection,
IntPtr rawMessage,
IntPtr userData)
{
Message message = Message.Wrap(rawMessage, Service);
if (message.Type == Message.MessageType.Signal) {
Signal signal = (Signal) message;
} else if (message.Type == Message.MessageType.MethodCall) {
MethodCall methodCall = (MethodCall) message;
}
return (int) Result.NotYetHandled;
}
public void Unregister_Called(IntPtr rawConnection,
IntPtr userData)
{
System.Console.WriteLine("FIXME: Unregister called.");
}
private int Message_Called(IntPtr rawConnection,
IntPtr rawMessage,
IntPtr userData)
{
Message message = Message.Wrap(rawMessage, Service);
switch (message.Type) {
case Message.MessageType.Signal:
System.Console.WriteLine("FIXME: Signal called.");
break;
case Message.MessageType.MethodCall:
return (int) HandleMethod((MethodCall) message);
}
return (int) Result.NotYetHandled;
}
private Result HandleMethod(MethodCall methodCall)
{
methodCall.Service = service;
// Check the interface name matches
if (methodCall.InterfaceName != this.introspector.InterfaceName) {
return Result.NotYetHandled;
}
// Iterate through getting the type codes
string key = methodCall.Name + " " + methodCall.Arguments;
// Check it's one of our methods
if (!handledMethods.Contains(key)) {
return Result.NotYetHandled;
}
// Got it!
MethodInfo method = (MethodInfo) handledMethods[key];
// Now call the method. FIXME: Error handling
object [] args = methodCall.Arguments.GetParameters(method);
object retVal = method.Invoke(this.handledObject, args);
// Create the reply and send it
MethodReturn methodReturn = new MethodReturn(methodCall);
methodReturn.Arguments.AppendResults(method, retVal, args);
methodReturn.Send();
return Result.Handled;
}
internal string[] Path
{
get
{
return path;
}
}
public string PathName
{
get
{
return pathName;
}
}
internal Connection Connection
{
get
{
return connection;
}
set
{
this.connection = value;
}
}
public Service Service
{
get
{
return service;
}
set
{
this.service = value;
}
}
[DllImport ("dbus-1")]
private extern static bool dbus_connection_register_object_path (IntPtr rawConnection, string[] path, ref DBusObjectPathVTable vTable, IntPtr userData);
[DllImport ("dbus-1")]
private extern static void dbus_connection_unregister_object_path (IntPtr rawConnection, string[] path);
[DllImport ("dbus-1")]
private extern static bool dbus_connection_add_filter(IntPtr rawConnection,
DBusHandleMessageFunction filter,
IntPtr userData,
IntPtr freeData);
}
}
--- NEW FILE: InterfaceAttribute.cs ---
using System;
namespace DBus
{
[AttributeUsage(AttributeTargets.Class, AllowMultiple=false, Inherited=true)]
public class InterfaceAttribute : Attribute
{
private string interfaceName;
public InterfaceAttribute(string interfaceName)
{
this.interfaceName = interfaceName;
}
public string InterfaceName
{
get
{
return this.interfaceName;
}
}
}
}
--- NEW FILE: Introspector.cs ---
namespace DBus
{
using System;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Collections;
using System.Reflection;
internal class Introspector
{
private Type type;
private string interfaceName;
public Introspector(Type type) {
object[] attributes = type.GetCustomAttributes(typeof(InterfaceAttribute), true);
if (attributes.Length != 1)
throw new ApplicationException("Type '" + type + "' is not a D-BUS interface.");
InterfaceAttribute interfaceAttribute = (InterfaceAttribute) attributes[0];
this.interfaceName = interfaceAttribute.InterfaceName;
this.type = type;
}
public string InterfaceName
{
get
{
return this.interfaceName;
}
}
public ConstructorInfo Constructor
{
get
{
ConstructorInfo ret = this.type.GetConstructor(new Type[0]);
if (ret != null) {
return ret;
} else {
return typeof(object).GetConstructor(new Type[0]);
}
}
}
public IntrospectorMethods Methods
{
get
{
return new IntrospectorMethods(this.type);
}
}
public class IntrospectorMethods : IEnumerable
{
private Type type;
public IntrospectorMethods(Type type)
{
this.type = type;
}
public IEnumerator GetEnumerator()
{
return new MethodEnumerator(this.type.GetMethods(BindingFlags.Public|BindingFlags.Instance).GetEnumerator());
}
private class MethodEnumerator : IEnumerator
{
private IEnumerator enumerator;
public MethodEnumerator(IEnumerator enumerator)
{
this.enumerator = enumerator;
}
public bool MoveNext()
{
while (enumerator.MoveNext()) {
MethodInfo method = (MethodInfo) enumerator.Current;
object[] attributes = method.GetCustomAttributes(typeof(MethodAttribute), true);
if (attributes.GetLength(0) > 0) {
return true;
}
}
return false;
}
public void Reset()
{
enumerator.Reset();
}
public object Current
{
get
{
return enumerator.Current;
}
}
}
}
}
}
--- NEW FILE: MethodAttribute.cs ---
using System;
namespace DBus
{
[AttributeUsage(AttributeTargets.Method, AllowMultiple=false, Inherited=true)]
public class MethodAttribute : Attribute
{
public MethodAttribute()
{
}
}
}
--- NEW FILE: MethodCall.cs ---
namespace DBus
{
using System;
using System.Runtime.InteropServices;
using System.Diagnostics;
public class MethodCall : Message
{
public MethodCall() : base(MessageType.MethodCall)
{
}
internal MethodCall(IntPtr rawMessage, Service service) : base(rawMessage, service)
{
}
public MethodCall(Service service) : base(MessageType.MethodCall, service)
{
}
public MethodCall(Service service, string pathName, string interfaceName, string name)
{
this.service = service;
RawMessage = dbus_message_new_method_call(service.Name, pathName, interfaceName, name);
if (RawMessage == IntPtr.Zero) {
throw new OutOfMemoryException();
}
this.pathName = pathName;
this.interfaceName = interfaceName;
this.name = name;
dbus_message_unref(RawMessage);
}
public new string PathName
{
get
{
return base.PathName;
}
set
{
base.PathName = value;
}
}
public new string InterfaceName
{
get
{
return base.InterfaceName;
}
set
{
base.InterfaceName = value;
}
}
public new string Name
{
get
{
return base.Name;
}
set
{
base.Name = value;
}
}
[DllImport("dbus-1")]
private extern static IntPtr dbus_message_new_method_call(string serviceName, string pathName, string interfaceName, string name);
}
}
--- NEW FILE: MethodReturn.cs ---
namespace DBus
{
using System;
using System.Runtime.InteropServices;
using System.Diagnostics;
public class MethodReturn : Message
{
private MethodReturn() : base(MessageType.MethodReturn)
{
}
internal MethodReturn(IntPtr rawMessage, Service service) : base(rawMessage, service)
{
}
public MethodReturn(MethodCall methodCall)
{
this.service = methodCall.Service;
RawMessage = dbus_message_new_method_return(methodCall.RawMessage);
if (RawMessage == IntPtr.Zero) {
throw new OutOfMemoryException();
}
dbus_message_unref(RawMessage);
}
public new string PathName
{
get
{
return base.PathName;
}
}
public new string InterfaceName
{
get
{
return base.InterfaceName;
}
}
public new string Name
{
get
{
return base.Name;
}
}
[DllImport("dbus-1")]
private extern static IntPtr dbus_message_new_method_return(IntPtr rawMessage);
}
}
--- NEW FILE: ProxyBuilder.cs ---
namespace DBus
{
using System;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Collections;
using System.Threading;
using System.Reflection;
using System.Reflection.Emit;
internal class ProxyBuilder
{
private Service service= null;
private string pathName = null;
private Type type = null;
private Introspector introspector = null;
private AssemblyBuilder proxyAssembly;
private static MethodInfo Service_NameMI = typeof(Service).GetMethod("get_Name",
new Type[0]);
private static MethodInfo Service_ConnectionMI = typeof(Service).GetMethod("get_Connection",
new Type[0]);
private static MethodInfo Message_ArgumentsMI = typeof(Message).GetMethod("get_Arguments",
new Type[0]);
private static MethodInfo Arguments_InitAppendingMI = typeof(Arguments).GetMethod("InitAppending",
new Type[0]);
private static MethodInfo Arguments_AppendMI = typeof(Arguments).GetMethod("Append",
new Type[] {typeof(DBusType.IDBusType)});
private static MethodInfo Message_SendWithReplyAndBlockMI = typeof(Message).GetMethod("SendWithReplyAndBlock",
new Type[0]);
private static MethodInfo Arguments_GetEnumeratorMI = typeof(Arguments).GetMethod("GetEnumerator",
new Type[0]);
private static MethodInfo IEnumerator_MoveNextMI = typeof(System.Collections.IEnumerator).GetMethod("MoveNext",
new Type[0]);
private static MethodInfo IEnumerator_CurrentMI = typeof(System.Collections.IEnumerator).GetMethod("get_Current",
new Type[0]);
private static MethodInfo Type_GetTypeFromHandleMI = typeof(System.Type).GetMethod("GetTypeFromHandle",
new Type[] {typeof(System.RuntimeTypeHandle)});
private static MethodInfo IDBusType_GetMI = typeof(DBusType.IDBusType).GetMethod("Get",
new Type[] {typeof(System.Type)});
private static ConstructorInfo MethodCall_C = typeof(MethodCall).GetConstructor(new Type[] {typeof(Service),
typeof(string),
typeof(string),
typeof(string)});
public ProxyBuilder(Service service, Type type, string pathName)
{
this.service = service;
this.pathName = pathName;
this.type = type;
this.introspector = new Introspector(type);
}
private void BuildMethod(MethodInfo method,
ref TypeBuilder typeB,
FieldInfo serviceF,
FieldInfo interfaceF,
FieldInfo pathF)
{
ParameterInfo[] pars = method.GetParameters();
Type[] parTypes = new Type[pars.Length];
for (int parN = 0; parN < pars.Length; parN++) {
parTypes[parN] = pars[parN].ParameterType;
}
// Generate the code
MethodBuilder methodBuilder = typeB.DefineMethod(method.Name,
MethodAttributes.Public |
MethodAttributes.HideBySig |
MethodAttributes.Virtual,
method.ReturnType,
parTypes);
ILGenerator generator = methodBuilder.GetILGenerator();
for (int parN = 0; parN < pars.Length; parN++) {
methodBuilder.DefineParameter(parN + 1, pars[parN].Attributes, pars[parN].Name);
}
// Generate the locals
LocalBuilder methodCallL = generator.DeclareLocal(typeof(MethodCall));
methodCallL.SetLocalSymInfo("methodCall");
LocalBuilder replyL = generator.DeclareLocal(typeof(MethodReturn));
replyL.SetLocalSymInfo("reply");
LocalBuilder enumeratorL = generator.DeclareLocal(typeof(System.Collections.IEnumerator));
enumeratorL.SetLocalSymInfo("enumerator");
if (method.ReturnType != typeof(void)) {
LocalBuilder retvalL = generator.DeclareLocal(method.ReturnType);
retvalL.SetLocalSymInfo("retval");
}
//generator.EmitWriteLine("MethodCall methodCall = new MethodCall(...)");
generator.Emit(OpCodes.Ldsfld, serviceF);
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Ldfld, pathF);
generator.Emit(OpCodes.Ldsfld, interfaceF);
generator.Emit(OpCodes.Ldstr, method.Name);
generator.Emit(OpCodes.Newobj, MethodCall_C);
generator.Emit(OpCodes.Stloc_0);
//generator.EmitWriteLine("methodCall.Arguments.InitAppending()");
generator.Emit(OpCodes.Ldloc_0);
generator.EmitCall(OpCodes.Callvirt, Message_ArgumentsMI, null);
generator.EmitCall(OpCodes.Callvirt, Arguments_InitAppendingMI, null);
for (int parN = 0; parN < pars.Length; parN++) {
ParameterInfo par = pars[parN];
if (!par.IsOut) {
EmitIn(generator, par.ParameterType, parN);
}
}
//generator.EmitWriteLine("MethodReturn reply = methodCall.SendWithReplyAndBlock()");
generator.Emit(OpCodes.Ldloc_0);
generator.EmitCall(OpCodes.Callvirt, Message_SendWithReplyAndBlockMI, null);
generator.Emit(OpCodes.Stloc_1);
//generator.EmitWriteLine("IEnumerator enumeartor = reply.Arguments.GetEnumerator()");
generator.Emit(OpCodes.Ldloc_1);
generator.EmitCall(OpCodes.Callvirt, Message_ArgumentsMI, null);
generator.EmitCall(OpCodes.Callvirt, Arguments_GetEnumeratorMI, null);
generator.Emit(OpCodes.Stloc_2);
// handle the return value
if (method.ReturnType != typeof(void)) {
EmitOut(generator, method.ReturnType, 0);
}
for (int parN = 0; parN < pars.Length; parN++) {
ParameterInfo par = pars[parN];
if (par.IsOut || par.ParameterType.ToString().EndsWith("&")) {
EmitOut(generator, par.ParameterType, parN);
}
}
if (method.ReturnType != typeof(void)) {
generator.Emit(OpCodes.Ldloc_3);
}
generator.Emit(OpCodes.Ret);
// Generate the method
typeB.DefineMethodOverride(methodBuilder, method);
}
private void EmitIn(ILGenerator generator, Type parType, int parN)
{
Type inParType = Arguments.MatchType(parType);
//generator.EmitWriteLine("methodCall.Arguments.Append(...)");
generator.Emit(OpCodes.Ldloc_0);
generator.EmitCall(OpCodes.Callvirt, Message_ArgumentsMI, null);
generator.Emit(OpCodes.Ldarg_S, parN + 1);
// Call the DBusType EmitMarshalIn to make it emit itself
object[] pars = new object[] {generator, parType};
inParType.InvokeMember("EmitMarshalIn", BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod, null, null, pars, null);
generator.Emit(OpCodes.Newobj, Arguments.GetDBusTypeConstructor(inParType, parType));
generator.EmitCall(OpCodes.Callvirt, Arguments_AppendMI, null);
}
private void EmitOut(ILGenerator generator, Type parType, int parN)
{
Type outParType = Arguments.MatchType(parType);
//generator.EmitWriteLine("enumerator.MoveNext()");
generator.Emit(OpCodes.Ldloc_2);
generator.EmitCall(OpCodes.Callvirt, IEnumerator_MoveNextMI, null);
//generator.EmitWriteLine("return (" + parType + ") ((DBusType.IDBusType) enumerator.Current).Get(typeof(" + parType + "))");
generator.Emit(OpCodes.Pop);
if (parN > 0) {
generator.Emit(OpCodes.Ldarg_S, parN + 1);
}
generator.Emit(OpCodes.Ldloc_2);
generator.EmitCall(OpCodes.Callvirt, IEnumerator_CurrentMI, null);
generator.Emit(OpCodes.Castclass, typeof(DBusType.IDBusType));
generator.Emit(OpCodes.Ldtoken, parType);
generator.EmitCall(OpCodes.Call, Type_GetTypeFromHandleMI, null);
generator.EmitCall(OpCodes.Callvirt, IDBusType_GetMI, null);
// Call the DBusType EmitMarshalOut to make it emit itself
object[] pars = new object[] {generator, parType, parN == 0};
outParType.InvokeMember("EmitMarshalOut", BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod, null, null, pars, null);
if (parN == 0) {
generator.Emit(OpCodes.Stloc_3);
}
}
public void BuildConstructor(ref TypeBuilder typeB, FieldInfo serviceF, FieldInfo interfaceF, FieldInfo pathF)
{
Type[] pars = {typeof(Service), typeof(string), typeof(string)};
ConstructorBuilder constructor = typeB.DefineConstructor(MethodAttributes.RTSpecialName |
MethodAttributes.Public,
CallingConventions.Standard, pars);
ILGenerator generator = constructor.GetILGenerator();
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Call, this.introspector.Constructor);
generator.Emit(OpCodes.Ldarg_1);
generator.Emit(OpCodes.Stsfld, serviceF);
generator.Emit(OpCodes.Ldarg_2);
generator.Emit(OpCodes.Stsfld, interfaceF);
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Ldarg_3);
generator.Emit(OpCodes.Stfld, pathF);
generator.Emit(OpCodes.Ret);
}
public object GetProxy()
{
// Build the type
TypeBuilder typeB = ServiceModuleBuilder.DefineType(ProxyName, TypeAttributes.Public, this.type);
//type.AddInterfaceImplementation(typeof(IProxy));
FieldBuilder serviceF = typeB.DefineField("service",
typeof(Service),
FieldAttributes.Private |
FieldAttributes.Static);
FieldBuilder interfaceF = typeB.DefineField("interfaceName",
typeof(string),
FieldAttributes.Private |
FieldAttributes.Static);
FieldBuilder pathF = typeB.DefineField("pathName",
typeof(string),
FieldAttributes.Private);
BuildConstructor(ref typeB, serviceF, interfaceF, pathF);
// Build the methods
foreach (MethodInfo method in this.introspector.Methods) {
BuildMethod(method, ref typeB, serviceF, interfaceF, pathF);
}
Type [] parTypes = new Type[] {typeof(Service), typeof(string), typeof(string)};
object [] pars = new object[] {Service, this.introspector.InterfaceName, pathName};
Type proxyType = typeB.CreateType();
// Uncomment the following line to produce a DLL of the
// constructed assembly which can then be examined using
// monodis. Note that in order for this to work you should copy
// the client assembly as a dll file so that monodis can pick it
// up.
//ProxyAssembly.Save("proxy.dll");
ConstructorInfo constructor = proxyType.GetConstructor(parTypes);
object instance = constructor.Invoke(pars);
return instance;
}
private ModuleBuilder ServiceModuleBuilder
{
get
{
if (Service.module == null) {
Service.module = ProxyAssembly.DefineDynamicModule(Service.Name, "proxy.dll", true);
}
return Service.module;
}
}
private Service Service
{
get
{
return this.service;
}
}
private string ProxyName
{
get
{
return this.introspector.InterfaceName + ".Proxy";
}
}
private AssemblyBuilder ProxyAssembly
{
get
{
if (this.proxyAssembly == null){
AssemblyName assemblyName = new AssemblyName();
assemblyName.Name = "DBusProxy";
this.proxyAssembly = Thread.GetDomain().DefineDynamicAssembly(assemblyName,
AssemblyBuilderAccess.RunAndSave);
}
return this.proxyAssembly;
}
}
}
}
--- NEW FILE: README ---
D-BUS Mono Bindings
===
These bindings are a 'thick' wrapper around the D-BUS API. For now
they rely on the main loop provided by the GLib bindings but this
dependancy will be removed in the near future.
The wrapper serves two main functions: firstly, it has the know-how to
introspect live objects passed to it by a server and service requests
to those objects via the D-BUS. Secondly, it can create a proxy for
clients who can pretend they are making calls to the regular
objects. This latter piece of magic is implemented using
Reflection.Emit to create an assembly on-the-fly containing
sub-classes of the classes the client thinks it's really using. These
sub-classes simply marshal each method's parameters off to the D-BUS,
demarshal the results and return them to the client as if nothing
happened.
Usage
===
A server do should something like this:
namespace Foo
{
using System;
using DBus;
using Gtk;
public class MyServer
{
public static int Main(string [] args)
{
Application.Init();
1 Connection connection = Bus.GetSessionBus();
2 Service service = new Service(connection, "org.foo");
3 MyObject myObject = new MyObject();
4 service.RegisterObject(myObject, "/org/foo/MyObject");
Application.Run();
return 0;
}
}
}
In line 1 we get a connection to the session bus. Then, in line 2 we
create a service which will listen for requests to org.foo to
service. In line 3 we create a MyObject object and register it with an
object path in line 4. It's almost that simple. All that's missing is
to mark MyObject in such a way that dbus-sharp knows how to export
it. This is done using the attributes, Interface and Method,
as in the following example:
namespace Foo
{
using System;
using DBus;
[Interface("org.foo.MyObject")]
public class MyObject
{
[Method]
public virtual string Echo(string message)
{
return "Reply: " + message;
}
}
}
Note that the Methods should also be declared virtual in order for
the client to use same class declaration.
Now for the client:
namespace Foo
{
using System;
using DBus;
public class MyClient
{
public static int Main(string [] args)
{
1 Connection connection = Bus.GetSessionBus();
2 Service service = Service.Get(connection, "org.foo");
3 MyObject myObject = (MyObject)
service.GetObject(typeof(MyObject), "/org/foo/MyObject");
4 System.Console.WriteLine(testObject.Echo("Hello world!"));
return 0;
}
}
}
Here we start off the same by getting a connection to the session
bus. This time though, in line 2, we get the existing service rather
than creating it. In line 3, we ask the service to get the object
"/org/foo/MyObject" as registered by the server and that return it as
a MyObject. Once obtained we can use it like any normal object as in
line 4. This supposes, of course, that you've just written MyObject
and happen to have it readily available. If that were not the case,
for example if you wanted to call a method on one of the well-known
services, then you will need to write a stub class, like the MyObject
class above, which has the method calls you need correctly defined but
needn't actually have any implementation.
Working Example
===
The example directory contains a working example similar to that
described above. It uses the session bus so first run dbus-launch and
then export DBUS_SESSION_BUS_ADDRESS, as displayed by dbus-launch, to
two terminals, one to run the server and one for the client. Then,
start the server in one terminal, the client in the other and cross
your fingers.
--- NEW FILE: Server.cs ---
namespace DBus
{
using System;
using System.Runtime.InteropServices;
using System.Diagnostics;
public class Server
{
private IntPtr rawServer;
/// <summary>
/// The current slot number
/// </summary>
private static int slot = -1;
private string address = null;
private Server(IntPtr rawServer)
{
RawServer = rawServer;
}
public Server(string address)
{
Error error = new Error();
error.Init();
RawServer = dbus_server_listen(address, ref error);
if (RawServer != IntPtr.Zero){
dbus_server_unref(RawServer);
} else {
throw new DBusException(error);
}
}
~Server()
{
if (RawServer != IntPtr.Zero) {
dbus_server_unref(rawServer);
}
RawServer = IntPtr.Zero;
}
public string Address
{
get
{
if (address == null) {
address = dbus_server_get_address(rawServer);
}
return address;
}
}
private int Slot
{
get
{
if (slot == -1)
{
// We need to initialize the slot
if (!dbus_server_allocate_data_slot (ref slot))
throw new OutOfMemoryException ();
Debug.Assert (slot >= 0);
}
return slot;
}
}
internal IntPtr RawServer
{
get
{
return rawServer;
}
set
{
if (value == rawServer)
return;
if (rawServer != IntPtr.Zero)
{
// Get the reference to this
IntPtr rawThis = dbus_server_get_data (rawServer, Slot);
Debug.Assert (rawThis != IntPtr.Zero);
// Blank over the reference
dbus_server_set_data (rawServer, Slot, IntPtr.Zero, IntPtr.Zero);
// Free the reference
((GCHandle) rawThis).Free();
// Unref the connection
dbus_server_unref(rawServer);
}
this.rawServer = value;
if (rawServer != IntPtr.Zero)
{
GCHandle rawThis;
dbus_server_ref (rawServer);
// We store a weak reference to the C# object on the C object
rawThis = GCHandle.Alloc (this, GCHandleType.WeakTrackResurrection);
dbus_server_set_data(rawServer, Slot, (IntPtr) rawThis, IntPtr.Zero);
}
}
}
[DllImport ("dbus-1", EntryPoint="dbus_server_listen")]
private extern static IntPtr dbus_server_listen(string address, ref Error error);
[DllImport ("dbus-1", EntryPoint="dbus_server_unref")]
private extern static IntPtr dbus_server_unref(IntPtr rawServer);
[DllImport ("dbus-1", EntryPoint="dbus_server_ref")]
private extern static void dbus_server_ref(IntPtr rawServer);
[DllImport ("dbus-1", EntryPoint="dbus_server_disconnect")]
private extern static void dbus_server_disconnect(IntPtr rawServer);
[DllImport ("dbus-1", EntryPoint="dbus_server_get_address")]
private extern static string dbus_server_get_address(IntPtr rawServer);
[DllImport ("dbus-1", EntryPoint="dbus_server_set_data")]
private extern static bool dbus_server_set_data(IntPtr rawServer,
int slot,
IntPtr data,
IntPtr freeDataFunc);
[DllImport ("dbus-1", EntryPoint="dbus_server_get_data")]
private extern static IntPtr dbus_server_get_data(IntPtr rawServer,
int slot);
[DllImport ("dbus-1", EntryPoint="dbus_server_allocate_data_slot")]
private extern static bool dbus_server_allocate_data_slot (ref int slot);
[DllImport ("dbus-1", EntryPoint="dbus_server_free_data_slot")]
private extern static void dbus_server_free_data_slot (ref int slot);
}
}
--- NEW FILE: Service.cs ---
namespace DBus
{
using System;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Collections;
using System.Reflection;
using System.Reflection.Emit;
public class Service
{
private Connection connection;
private string name;
private bool local = false;
private Hashtable registeredHandlers = new Hashtable();
internal ModuleBuilder module = null;
internal Service(string name, Connection connection)
{
this.name = name;
this.connection = connection;
}
public Service(Connection connection, string name)
{
Error error = new Error();
error.Init();
// This isn't used for now
uint flags = 0;
if (dbus_bus_acquire_service(connection.RawConnection, name, flags, ref error) == -1) {
throw new DBusException(error);
}
this.connection = connection;
this.name = name;
this.local = true;
}
public static bool Exists(Connection connection, string name)
{
Error error = new Error();
error.Init();
if (dbus_bus_service_exists(connection.RawConnection,
name,
ref error)) {
return true;
} else {
if (error.IsSet) {
throw new DBusException(error);
}
return false;
}
}
public static Service Get(Connection connection, string name)
{
if (Exists(connection, name)) {
return new Service(name, connection);
} else {
throw new ApplicationException("Service '" + name + "' does not exist.");
}
}
public void RegisterObject(object handledObject,
string pathName)
{
Handler handler = new Handler(handledObject,
pathName,
this);
registeredHandlers.Add(handledObject, handler);
}
internal Handler GetHandler(object handledObject)
{
return (Handler) registeredHandlers[handledObject];
}
public object GetObject(Type type, string pathName)
{
ProxyBuilder builder = new ProxyBuilder(this, type, pathName);
object proxy = builder.GetProxy();
return proxy;
}
public string Name
{
get
{
return this.name;
}
}
public Connection Connection
{
get
{
return connection;
}
set
{
this.connection = value;
}
}
[DllImport ("dbus-1")]
private extern static int dbus_bus_acquire_service (IntPtr rawConnection, string serviceName, uint flags, ref Error error);
[DllImport ("dbus-1")]
private extern static bool dbus_bus_service_exists (IntPtr rawConnection, string serviceName, ref Error error);
}
}
--- NEW FILE: Signal.cs ---
namespace DBus
{
using System;
using System.Runtime.InteropServices;
using System.Diagnostics;
public class Signal : Message
{
public Signal() : base(MessageType.Signal)
{
}
internal Signal(IntPtr rawMessage, Service service) : base(rawMessage, service)
{
}
public Signal(Service service) : base(MessageType.Signal, service)
{
}
public new string PathName
{
get
{
return base.PathName;
}
set
{
base.PathName = value;
}
}
public new string InterfaceName
{
get
{
return base.InterfaceName;
}
set
{
base.InterfaceName = value;
}
}
public new string Name
{
get
{
return base.Name;
}
set
{
base.Name = value;
}
}
}
}
--- NEW FILE: TODO ---
- Clean up memory leakages. Call _unref functions etc.
- Convert strings to/from UTF-8
- Implement own main loop. The current implementation depends on the
GLib mainloop.
- Get test working. Probably a threading issue.
Index: Connection.cs
===================================================================
RCS file: /cvs/dbus/dbus/mono/Connection.cs,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- a/Connection.cs 3 Jul 2003 01:48:31 -0000 1.4
+++ b/Connection.cs 23 Mar 2004 12:10:32 -0000 1.5
@@ -1,192 +1,180 @@
-namespace DBus {
-
- using System;
- using System.Runtime.InteropServices;
- using System.Diagnostics;
-
- public class Connection {
-
- public Connection (string address) {
- // the assignment bumps the refcount
- Error error = new Error ();
- error.Init ();
- raw = dbus_connection_open (address, ref error);
- if (raw != IntPtr.Zero) {
- dbus_connection_unref (raw);
- } else {
- Exception e = new Exception (ref error);
- error.Free ();
- throw e;
- }
- dbus_connection_setup_with_g_main (raw, IntPtr.Zero);
- }
-
- // Keep in sync with C
- public enum BusType {
- Session = 0,
- System = 1,
- Activation = 2
- }
-
- public static Connection GetBus (BusType bus) {
- Error error = new Error ();
-
- error.Init ();
-
- IntPtr ptr = dbus_bus_get ((int) bus, ref error);
- if (ptr != IntPtr.Zero) {
- Connection c = Wrap (ptr);
- dbus_connection_unref (ptr);
- return c;
- } else {
- Exception e = new Exception (ref error);
- error.Free ();
- throw e;
- }
- }
-
- public void Send (Message m,
- ref int serial) {
- if (!dbus_connection_send (raw, m.raw, ref serial))
- throw new OutOfMemoryException ();
- }
-
- public void Send (Message m) {
- int ignored = 0;
- Send (m, ref ignored);
- }
-
- public void Flush () {
- dbus_connection_flush (raw);
- }
-
- public void Disconnect () {
- dbus_connection_disconnect (raw);
- }
-
- public static Connection Wrap (IntPtr ptr) {
- IntPtr gch_ptr;
-
- gch_ptr = dbus_connection_get_data (ptr, wrapper_slot);
- if (gch_ptr != IntPtr.Zero) {
- return (DBus.Connection) ((GCHandle)gch_ptr).Target;
- } else {
- return new Connection (ptr);
- }
- }
-
- // surely there's a convention for this pattern with the property
- // and the real member
- IntPtr raw_;
- internal IntPtr raw {
- get {
- return raw_;
- }
- set {
- if (value == raw_)
- return;
-
- if (raw_ != IntPtr.Zero) {
- IntPtr gch_ptr;
-
- gch_ptr = dbus_connection_get_data (raw_,
- wrapper_slot);
- Debug.Assert (gch_ptr != IntPtr.Zero);
-
- dbus_connection_set_data (raw_, wrapper_slot,
- IntPtr.Zero, IntPtr.Zero);
-
- ((GCHandle) gch_ptr).Free ();
-
- dbus_connection_unref (raw_);
- }
-
- raw_ = value;
-
- if (raw_ != IntPtr.Zero) {
- GCHandle gch;
-
- dbus_connection_ref (raw_);
-
- // We store a weak reference to the C# object on the C object
- gch = GCHandle.Alloc (this, GCHandleType.WeakTrackResurrection);
-
- dbus_connection_set_data (raw_, wrapper_slot,
- (IntPtr) gch, IntPtr.Zero);
- }
- }
- }
-
- ~Connection () {
- if (raw != IntPtr.Zero) {
- Disconnect ();
- }
- raw = IntPtr.Zero; // free the native object
- }
-
- Connection (IntPtr r) {
- raw = r;
- }
-
- // static constructor runs before any methods
- static Connection () {
- DBus.Internals.Init ();
-
- Debug.Assert (wrapper_slot == -1);
-
- if (!dbus_connection_allocate_data_slot (ref wrapper_slot))
- throw new OutOfMemoryException ();
-
- Debug.Assert (wrapper_slot >= 0);
- }
-
- // slot used to store the C# object on the C object
- static int wrapper_slot = -1;
-
- [DllImport (DBus.Internals.DBusLibname, EntryPoint="dbus_connection_open")]
- private extern static IntPtr dbus_connection_open (string address,
- ref Error error);
-
- [DllImport (DBus.Internals.DBusLibname, EntryPoint="dbus_connection_unref")]
- private extern static void dbus_connection_unref (IntPtr ptr);
-
- [DllImport (DBus.Internals.DBusLibname, EntryPoint="dbus_connection_ref")]
- private extern static void dbus_connection_ref (IntPtr ptr);
-
- [DllImport (DBus.Internals.DBusLibname, EntryPoint="dbus_connection_allocate_data_slot")]
- private extern static bool dbus_connection_allocate_data_slot (ref int slot);
-
- [DllImport (DBus.Internals.DBusLibname, EntryPoint="dbus_connection_free_data_slot")]
- private extern static void dbus_connection_free_data_slot (ref int slot);
-
- [DllImport (DBus.Internals.DBusLibname, EntryPoint="dbus_connection_set_data")]
- private extern static bool dbus_connection_set_data (IntPtr ptr,
- int slot,
- IntPtr data,
- IntPtr free_data_func);
-
- [DllImport (DBus.Internals.DBusLibname, EntryPoint="dbus_connection_send")]
- private extern static bool dbus_connection_send (IntPtr ptr,
- IntPtr message,
- ref int client_serial);
-
- [DllImport (DBus.Internals.DBusLibname, EntryPoint="dbus_connection_flush")]
- private extern static void dbus_connection_flush (IntPtr ptr);
-
- [DllImport (DBus.Internals.DBusLibname, EntryPoint="dbus_bus_get")]
- private extern static IntPtr dbus_bus_get (int which,
- ref Error error);
-
- [DllImport (DBus.Internals.DBusLibname, EntryPoint="dbus_connection_get_data")]
- private extern static IntPtr dbus_connection_get_data (IntPtr ptr,
- int slot);
-
- [DllImport (DBus.Internals.DBusLibname, EntryPoint="dbus_connection_disconnect")]
- private extern static void dbus_connection_disconnect (IntPtr ptr);
-
- [DllImport (DBus.Internals.DBusGLibname, EntryPoint="dbus_connection_setup_with_g_main")]
- private extern static void dbus_connection_setup_with_g_main (IntPtr ptr,
- IntPtr context);
-
- }
-}
+namespace DBus
+{
+
+ using System;
+ using System.Runtime.InteropServices;
+ using System.Diagnostics;
+ using System.Reflection;
+ using System.IO;
+ using System.Collections;
+
+ public class Connection
+ {
+ /// <summary>
+ /// A pointer to the underlying Connection structure
+ /// </summary>
+ private IntPtr rawConnection;
+
+ /// <summary>
+ /// The current slot number
+ /// </summary>
+ private static int slot = -1;
+
+ private int timeout = -1;
+
+ internal Connection(IntPtr rawConnection)
+ {
+ RawConnection = rawConnection;
+ }
+
+ public Connection(string address)
+ {
+ // the assignment bumps the refcount
+ Error error = new Error();
+ error.Init();
+ RawConnection = dbus_connection_open(address, ref error);
+ if (RawConnection != IntPtr.Zero) {
+ dbus_connection_unref(RawConnection);
+ } else {
+ throw new DBusException(error);
+ }
+
+ SetupWithMain();
+ }
+
+ public void SetupWithMain()
+ {
+ dbus_connection_setup_with_g_main(RawConnection, IntPtr.Zero);
+ }
+
+ ~Connection ()
+ {
+ if (RawConnection != IntPtr.Zero)
+ {
+ dbus_connection_disconnect(rawConnection);
+ }
+ RawConnection = IntPtr.Zero; // free the native object
+ }
+
+ internal static Connection Wrap(IntPtr rawConnection)
+ {
+ if (slot > -1) {
+ // If we already have a Connection object associated with this rawConnection then return it
+ IntPtr rawThis = dbus_connection_get_data (rawConnection, slot);
+ return (DBus.Connection) ((GCHandle)rawThis).Target;
+ }
+ else
+ {
+ // If it doesn't exist then create a new connection around it
+ return new Connection(rawConnection);
+ }
+ }
+
+ public int Timeout
+ {
+ get
+ {
+ return this.timeout;
+ }
+ set
+ {
+ this.timeout = value;
+ }
+ }
+
+ private int Slot
+ {
+ get
+ {
+ if (slot == -1)
+ {
+ // We need to initialize the slot
+ if (!dbus_connection_allocate_data_slot (ref slot))
+ throw new OutOfMemoryException ();
+
+ Debug.Assert (slot >= 0);
+ }
+
+ return slot;
+ }
+ }
+
+ internal IntPtr RawConnection
+ {
+ get
+ {
+ return rawConnection;
+ }
+ set
+ {
+ if (value == rawConnection)
+ return;
+
+ if (rawConnection != IntPtr.Zero)
+ {
+ // Get the reference to this
+ IntPtr rawThis = dbus_connection_get_data (rawConnection, Slot);
+ Debug.Assert (rawThis != IntPtr.Zero);
+
+ // Blank over the reference
+ dbus_connection_set_data (rawConnection, Slot, IntPtr.Zero, IntPtr.Zero);
+
+ // Free the reference
+ ((GCHandle) rawThis).Free();
+
+ // Unref the connection
+ dbus_connection_unref(rawConnection);
+ }
+
+ this.rawConnection = value;
+
+ if (rawConnection != IntPtr.Zero)
+ {
+ GCHandle rawThis;
+
+ dbus_connection_ref (rawConnection);
+
+ // We store a weak reference to the C# object on the C object
+ rawThis = GCHandle.Alloc (this, GCHandleType.WeakTrackResurrection);
+
+ dbus_connection_set_data(rawConnection, Slot, (IntPtr) rawThis, IntPtr.Zero);
+ }
+ }
+ }
+
+ [DllImport("dbus-glib-1")]
+ private extern static void dbus_connection_setup_with_g_main(IntPtr rawConnection,
+ IntPtr rawContext);
+
+ [DllImport ("dbus-1")]
+ private extern static IntPtr dbus_connection_open (string address, ref Error error);
+
+ [DllImport ("dbus-1")]
+ private extern static void dbus_connection_unref (IntPtr ptr);
+
+ [DllImport ("dbus-1")]
+ private extern static void dbus_connection_ref (IntPtr ptr);
+
+ [DllImport ("dbus-1")]
+ private extern static bool dbus_connection_allocate_data_slot (ref int slot);
+
+ [DllImport ("dbus-1")]
+ private extern static void dbus_connection_free_data_slot (ref int slot);
+
+ [DllImport ("dbus-1")]
+ private extern static bool dbus_connection_set_data (IntPtr ptr,
+ int slot,
+ IntPtr data,
+ IntPtr free_data_func);
+
+ [DllImport ("dbus-1")]
+ private extern static void dbus_connection_flush (IntPtr ptr);
+
+ [DllImport ("dbus-1")]
+ private extern static IntPtr dbus_connection_get_data (IntPtr ptr,
+ int slot);
+
+ [DllImport ("dbus-1")]
+ private extern static void dbus_connection_disconnect (IntPtr ptr);
+ }
+}
Index: Error.cs
===================================================================
RCS file: /cvs/dbus/dbus/mono/Error.cs,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- a/Error.cs 23 Jun 2003 02:12:19 -0000 1.2
+++ b/Error.cs 23 Mar 2004 12:10:32 -0000 1.3
@@ -1,29 +1,60 @@
-namespace DBus {
-
- using System;
- using System.Runtime.InteropServices;
-
- // FIXME add code to verify that size of DBus.Error
- // matches the C code.
-
- [StructLayout (LayoutKind.Sequential)]
- internal struct Error {
- internal IntPtr name;
- internal IntPtr message;
- private int dummies;
- private IntPtr padding1;
-
- internal void Init () {
- dbus_error_init (ref this);
- }
-
- internal void Free () {
- dbus_error_free (ref this);
- }
-
- [DllImport (DBus.Internals.DBusLibname, EntryPoint="dbus_error_init")]
- private extern static void dbus_error_init (ref Error error);
- [DllImport (DBus.Internals.DBusLibname, EntryPoint="dbus_error_free")]
- private extern static void dbus_error_free (ref Error error);
- }
-}
+namespace DBus
+{
+
+ using System;
+ using System.Runtime.InteropServices;
+ using System.Diagnostics;
+
+ // FIXME add code to verify that size of DBus.Error
+ // matches the C code.
+
+ [StructLayout (LayoutKind.Sequential)]
+ internal struct Error
+ {
+ internal IntPtr name;
+ internal IntPtr message;
+ private int dummies;
+ private IntPtr padding1;
+
+ public void Init()
+ {
+ dbus_error_init(ref this);
+ }
+
+ public void Free()
+ {
+ dbus_error_free(ref this);
+ }
+
+ public string Message
+ {
+ get
+ {
+ return System.Runtime.InteropServices.Marshal.PtrToStringAnsi(message);
+ }
+ }
+
+ public string Name
+ {
+ get
+ {
+ return System.Runtime.InteropServices.Marshal.PtrToStringAnsi(name);
+ }
+ }
+
+ public bool IsSet
+ {
+ get
+ {
+ return (name != IntPtr.Zero);
+ }
+ }
+
+
+ [DllImport ("dbus-1", EntryPoint="dbus_error_init")]
+ private extern static void dbus_error_init (ref Error error);
+
+ [DllImport ("dbus-1", EntryPoint="dbus_error_free")]
+ private extern static void dbus_error_free (ref Error error);
+ }
+}
Index: Makefile.am
===================================================================
RCS file: /cvs/dbus/dbus/mono/Makefile.am,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- a/Makefile.am 22 Jun 2003 22:59:31 -0000 1.2
+++ b/Makefile.am 23 Mar 2004 12:10:32 -0000 1.3
@@ -1,9 +1,41 @@
DESTDIR=
DLLS=dbus-sharp.dll
-NOINST_EXES=test-dbus-sharp
+NOINST_EXES=test-dbus-sharp.exe
+
+DBUS_SHARP_FILES= \
+ Arguments.cs \
+ Bus.cs \
+ Connection.cs \
+ Custom.cs \
+ DBusException.cs \
+ Error.cs \
+ Handler.cs \
+ InterfaceAttribute.cs \
+ Introspector.cs \
+ Message.cs \
+ MethodAttribute.cs \
+ MethodCall.cs \
+ MethodReturn.cs \
+ ProxyBuilder.cs \
+ Server.cs \
+ Service.cs \
+ Signal.cs \
+ DBusType/IDBusType.cs \
+ DBusType/Array.cs \
+ DBusType/Boolean.cs \
+ DBusType/Byte.cs \
+ DBusType/Custom.cs \
+ DBusType/Dict.cs \
+ DBusType/Double.cs \
+ DBusType/Int32.cs \
+ DBusType/Int64.cs \
+ DBusType/Nil.cs \
+ DBusType/ObjectPath.cs \
+ DBusType/String.cs \
+ DBusType/UInt32.cs \
+ DBusType/UInt64.cs
-DBUS_SHARP_FILES= DBus.cs Message.cs Connection.cs Error.cs
TEST_DBUS_SHARP_FILES=Test.cs
all: $(DLLS) $(NOINST_EXES)
@@ -11,8 +43,8 @@
dbus-sharp.dll: $(DBUS_SHARP_FILES)
$(MCS) $(MCSFLAGS) --unsafe --target library -o dbus-sharp.dll $(DBUS_SHARP_FILES)
-test-dbus-sharp: $(TEST_DBUS_SHARP_FILES)
- $(MCS) $(MCSFLAGS) --unsafe --target exe -L . -r dbus-sharp.dll -o test-dbus-sharp $(TEST_DBUS_SHARP_FILES)
+test-dbus-sharp.exe: $(TEST_DBUS_SHARP_FILES)
+ $(MCS) $(MCSFLAGS) --unsafe --target exe -L . -r dbus-sharp.dll -r gtk-sharp.dll -o test-dbus-sharp.exe $(TEST_DBUS_SHARP_FILES)
clean:
rm -f $(DLLS) $(NOINST_EXES)
Index: Message.cs
===================================================================
RCS file: /cvs/dbus/dbus/mono/Message.cs,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- a/Message.cs 25 Jun 2003 01:05:46 -0000 1.5
+++ b/Message.cs 23 Mar 2004 12:10:32 -0000 1.6
@@ -1,129 +1,358 @@
-namespace DBus {
-
- using System;
- using System.Runtime.InteropServices;
- using System.Diagnostics;
-
- public class Message {
-
- public Message (string name,
- string dest_service) {
- // the assignment bumps the refcount
- raw = dbus_message_new (name, dest_service);
- if (raw == IntPtr.Zero)
- throw new OutOfMemoryException ();
- dbus_message_unref (raw);
- }
-
- public string Name {
- get {
- return dbus_message_get_name (raw);
- }
- }
-
- public static Message Wrap (IntPtr ptr) {
- IntPtr gch_ptr;
-
- gch_ptr = dbus_message_get_data (ptr, wrapper_slot);
- if (gch_ptr != IntPtr.Zero) {
- return (DBus.Message) ((GCHandle)gch_ptr).Target;
- } else {
- return new Message (ptr);
- }
- }
-
- // surely there's a convention for this pattern with the property
- // and the real member
- IntPtr raw_;
- internal IntPtr raw {
- get {
- return raw_;
- }
- set {
- if (value == raw_)
- return;
-
- if (raw_ != IntPtr.Zero) {
- IntPtr gch_ptr;
-
- gch_ptr = dbus_message_get_data (raw_,
- wrapper_slot);
- Debug.Assert (gch_ptr != IntPtr.Zero);
-
- dbus_message_set_data (raw_, wrapper_slot,
- IntPtr.Zero, IntPtr.Zero);
-
- ((GCHandle) gch_ptr).Free ();
-
- dbus_message_unref (raw_);
- }
-
- raw_ = value;
-
- if (raw_ != IntPtr.Zero) {
- GCHandle gch;
-
- dbus_message_ref (raw_);
-
- // We store a weak reference to the C# object on the C object
- gch = GCHandle.Alloc (this, GCHandleType.WeakTrackResurrection);
-
- dbus_message_set_data (raw_, wrapper_slot,
- (IntPtr) gch, IntPtr.Zero);
- }
- }
- }
-
- ~Message () {
- raw = IntPtr.Zero; // free the native object
- }
-
- Message (IntPtr r) {
- raw = r;
- }
-
- // static constructor runs before any methods
- static Message () {
- DBus.Internals.Init ();
-
- Debug.Assert (wrapper_slot == -1);
-
- if (!dbus_message_allocate_data_slot (ref wrapper_slot))
- throw new OutOfMemoryException ();
-
- Debug.Assert (wrapper_slot >= 0);
- }
-
- // slot used to store the C# object on the C object
- static int wrapper_slot = -1;
-
- [DllImport (DBus.Internals.DBusLibname, EntryPoint="dbus_message_new")]
- private extern static IntPtr dbus_message_new (string name,
- string dest_service);
-
- [DllImport (DBus.Internals.DBusLibname, EntryPoint="dbus_message_unref")]
- private extern static void dbus_message_unref (IntPtr ptr);
-
- [DllImport (DBus.Internals.DBusLibname, EntryPoint="dbus_message_ref")]
- private extern static void dbus_message_ref (IntPtr ptr);
-
- [DllImport (DBus.Internals.DBusLibname, EntryPoint="dbus_message_get_name")]
- private extern static string dbus_message_get_name (IntPtr ptr);
-
- [DllImport (DBus.Internals.DBusLibname, EntryPoint="dbus_message_allocate_data_slot")]
- private extern static bool dbus_message_allocate_data_slot (ref int slot);
-
- [DllImport (DBus.Internals.DBusLibname, EntryPoint="dbus_message_free_data_slot")]
- private extern static void dbus_message_free_data_slot (ref int slot);
-
- [DllImport (DBus.Internals.DBusLibname, EntryPoint="dbus_message_set_data")]
- private extern static bool dbus_message_set_data (IntPtr ptr,
- int slot,
- IntPtr data,
- IntPtr free_data_func);
-
- [DllImport (DBus.Internals.DBusLibname, EntryPoint="dbus_message_get_data")]
- private extern static IntPtr dbus_message_get_data (IntPtr ptr,
- int slot);
- }
-}
+namespace DBus
+{
+
+ using System;
+ using System.Runtime.InteropServices;
+ using System.Diagnostics;
+ using System.Collections;
+
+ public class Message
+ {
+
+ /// <summary>
+ /// A pointer to the underlying Message structure
+ /// </summary>
+ private IntPtr rawMessage;
+
+ /// <summary>
+ /// The current slot number
+ /// </summary>
+ private static int slot = -1;
+
+ // Keep in sync with C
+ public enum MessageType
+ {
+ Invalid = 0,
+ MethodCall = 1,
+ MethodReturn = 2,
+ Error = 3,
+ Signal = 4
+ }
+
+ private Arguments arguments = null;
+
+ protected Service service = null;
+ protected string pathName = null;
+ protected string interfaceName = null;
+ protected string name = null;
+
+ protected Message()
+ {
+ // An empty constructor for the sake of sub-classes which know how to construct theirselves.
+ }
+
+ protected Message(IntPtr rawMessage, Service service)
+ {
+ RawMessage = rawMessage;
+ this.service = service;
+ }
+
+ protected Message(MessageType messageType)
+ {
+ // the assignment bumps the refcount
+ RawMessage = dbus_message_new((int) messageType);
+
+ if (RawMessage == IntPtr.Zero) {
+ throw new OutOfMemoryException();
+ }
+
+ dbus_message_unref(RawMessage);
+ }
+
+ protected Message(MessageType messageType, Service service) : this(messageType)
+ {
+ this.service = service;
+ }
+
+ ~Message()
+ {
+ RawMessage = IntPtr.Zero; // free the native object
+ }
+
+ public static Message Wrap(IntPtr rawMessage, Service service)
+ {
+ if (slot > -1) {
+ // If we already have a Message object associated with this rawMessage then return it
+ IntPtr rawThis = dbus_message_get_data(rawMessage, slot);
+ if (rawThis != IntPtr.Zero)
+ return (DBus.Message) ((GCHandle)rawThis).Target;
+ }
+ // If it doesn't exist then create a new Message around it
+ Message message = null;
+
+ switch ((MessageType) dbus_message_get_type(rawMessage)) {
+ case MessageType.Signal:
+ message = new Signal(rawMessage, service);
+ break;
+ case MessageType.MethodCall:
+ message = new MethodCall(rawMessage, service);
+ break;
+ }
+
+ return message;
+ }
+
+ internal IntPtr RawMessage
+ {
+ get
+ {
+ return rawMessage;
+ }
+ set
+ {
+ if (value == rawMessage)
+ return;
+
+ if (rawMessage != IntPtr.Zero)
+ {
+ // Get the reference to this
+ IntPtr rawThis = dbus_message_get_data(rawMessage, Slot);
+ Debug.Assert (rawThis != IntPtr.Zero);
+
+ // Blank over the reference
+ dbus_message_set_data(rawMessage, Slot, IntPtr.Zero, IntPtr.Zero);
+
+ // Free the reference
+ ((GCHandle) rawThis).Free();
+
+ // Unref the connection
+ dbus_message_unref(rawMessage);
+ }
+
+ this.rawMessage = value;
+
+ if (rawMessage != IntPtr.Zero)
+ {
+ GCHandle rawThis;
+
+ dbus_message_ref(rawMessage);
+
+ // We store a weak reference to the C# object on the C object
+ rawThis = GCHandle.Alloc(this, GCHandleType.WeakTrackResurrection);
+
+ dbus_message_set_data(rawMessage, Slot, (IntPtr) rawThis, IntPtr.Zero);
+ }
+ }
+ }
+
+ public void Send(ref int serial)
+ {
+ if (!dbus_connection_send (Service.Connection.RawConnection, RawMessage, ref serial))
+ throw new OutOfMemoryException ();
+ }
+
+ public void Send()
+ {
+ int ignored = 0;
+ Send(ref ignored);
+ }
+
+ public void SendWithReply()
+ {
+ IntPtr rawPendingCall = IntPtr.Zero;
+
+ if (!dbus_connection_send_with_reply (Service.Connection.RawConnection, RawMessage, rawPendingCall, Service.Connection.Timeout))
+ throw new OutOfMemoryException();
+ }
+
+ public MethodReturn SendWithReplyAndBlock()
+ {
+ Error error = new Error();
+ error.Init();
+
+ IntPtr rawMessage = dbus_connection_send_with_reply_and_block(Service.Connection.RawConnection,
+ RawMessage,
+ Service.Connection.Timeout,
+ ref error);
+
+ if (rawMessage != IntPtr.Zero) {
+ MethodReturn methodReturn = new MethodReturn(rawMessage, Service);
+ return methodReturn;
+ } else {
+ throw new DBusException(error);
+ }
+ }
+
+ public MessageType Type
+ {
+ get
+ {
+ return (MessageType) dbus_message_get_type(RawMessage);
+ }
+ }
+
+ public Service Service
+ {
+ set
+ {
+ if (this.service != null && (value.Name != this.service.Name)) {
+ if (!dbus_message_set_destination(RawMessage, value.Name)) {
+ throw new OutOfMemoryException();
+ }
+ }
+
+ this.service = value;
+ }
+ get
+ {
+ return this.service;
+ }
+ }
+
+ protected virtual string PathName
+ {
+ set
+ {
+ if (value != this.pathName)
+ {
+ if (!dbus_message_set_path(RawMessage, value)) {
+ throw new OutOfMemoryException();
+ }
+
+ this.pathName = value;
+ }
+ }
+ get
+ {
+ if (this.pathName == null) {
+ this.pathName = Marshal.PtrToStringAnsi(dbus_message_get_path(RawMessage));
+ }
+
+ return this.pathName;
+ }
+ }
+
+ protected virtual string InterfaceName
+ {
+ set
+ {
+ if (value != this.interfaceName)
+ {
+ dbus_message_set_interface (RawMessage, value);
+ this.interfaceName = value;
+ }
+ }
+ get
+ {
+ if (this.interfaceName == null) {
+ this.interfaceName = Marshal.PtrToStringAnsi(dbus_message_get_interface(RawMessage));
+ }
+
+ return this.interfaceName;
+ }
+ }
+
+ protected virtual string Name
+ {
+ set
+ {
+ if (value != this.name)
+ {
+ dbus_message_set_member (RawMessage, value);
+ this.name = value;
+ }
+ }
+ get
+ {
+ if (this.name == null) {
+ this.name = Marshal.PtrToStringAnsi(dbus_message_get_member(RawMessage));
+ }
+
+
+ return this.name;
+ }
+ }
+
+ public Arguments Arguments
+ {
+ get
+ {
+ if (this.arguments == null) {
+ this.arguments = new Arguments(this);
+ }
+
+ return this.arguments;
+ }
+ }
+
+ protected int Slot
+ {
+ get
+ {
+ if (slot == -1)
+ {
+ // We need to initialize the slot
+ if (!dbus_message_allocate_data_slot (ref slot))
+ throw new OutOfMemoryException ();
+
+ Debug.Assert (slot >= 0);
+ }
+
+ return slot;
+ }
+ }
+
+ [DllImport ("dbus-1", EntryPoint="dbus_message_new")]
+ protected extern static IntPtr dbus_message_new (int messageType);
+
+ [DllImport ("dbus-1", EntryPoint="dbus_message_unref")]
+ protected extern static void dbus_message_unref (IntPtr ptr);
+
+ [DllImport ("dbus-1", EntryPoint="dbus_message_ref")]
+ protected extern static void dbus_message_ref (IntPtr ptr);
+
+ [DllImport ("dbus-1", EntryPoint="dbus_message_allocate_data_slot")]
+ protected extern static bool dbus_message_allocate_data_slot (ref int slot);
+
+ [DllImport ("dbus-1", EntryPoint="dbus_message_free_data_slot")]
+ protected extern static void dbus_message_free_data_slot (ref int slot);
+
+ [DllImport ("dbus-1", EntryPoint="dbus_message_set_data")]
+ protected extern static bool dbus_message_set_data (IntPtr ptr,
+ int slot,
+ IntPtr data,
+ IntPtr free_data_func);
+
+ [DllImport ("dbus-1", EntryPoint="dbus_message_get_data")]
+ protected extern static IntPtr dbus_message_get_data (IntPtr ptr,
+ int slot);
+
+ [DllImport ("dbus-1", EntryPoint="dbus_connection_send")]
+ private extern static bool dbus_connection_send (IntPtr ptr,
+ IntPtr message,
+ ref int client_serial);
+
+ [DllImport ("dbus-1", EntryPoint="dbus_connection_send_with_reply")]
+ private extern static bool dbus_connection_send_with_reply (IntPtr rawConnection, IntPtr rawMessage, IntPtr rawPendingCall, int timeout);
+
+ [DllImport ("dbus-1", EntryPoint="dbus_connection_send_with_reply_and_block")]
+ private extern static IntPtr dbus_connection_send_with_reply_and_block (IntPtr rawConnection, IntPtr message, int timeout, ref Error error);
+
+ [DllImport("dbus-1")]
+ private extern static int dbus_message_get_type(IntPtr rawMessage);
+
+ [DllImport("dbus-1")]
+ private extern static bool dbus_message_set_path(IntPtr rawMessage, string pathName);
+
+ [DllImport("dbus-1")]
+ private extern static IntPtr dbus_message_get_path(IntPtr rawMessage);
+
+ [DllImport("dbus-1")]
+ private extern static bool dbus_message_set_interface (IntPtr rawMessage, string interfaceName);
+
+ [DllImport("dbus-1")]
+ private extern static IntPtr dbus_message_get_interface(IntPtr rawMessage);
+
+ [DllImport("dbus-1")]
+ private extern static bool dbus_message_set_member (IntPtr rawMessage, string name);
+
+ [DllImport("dbus-1")]
+ private extern static IntPtr dbus_message_get_member(IntPtr rawMessage);
+
+ [DllImport("dbus-1")]
+ private extern static bool dbus_message_set_destination(IntPtr rawMessage, string serviceName);
+
+ [DllImport("dbus-1")]
+ private extern static IntPtr dbus_message_get_destination(IntPtr rawMessage);
+ }
+}
Index: Test.cs
===================================================================
RCS file: /cvs/dbus/dbus/mono/Test.cs,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- a/Test.cs 3 Jul 2003 01:48:31 -0000 1.4
+++ b/Test.cs 23 Mar 2004 12:10:32 -0000 1.5
@@ -1,53 +1,70 @@
-
using System;
-using System.Runtime.InteropServices;
+using System.Threading;
+using DBus;
+using Gtk;
-class Test {
- static void Main() {
- g_thread_init (IntPtr.Zero);
+namespace DBus.Test
+{
+ public class Test
+ {
+ public static Service service = null;
+ public static Connection connection = null;
- DBus.Connection c;
+ public static int Main(string [] args)
+ {
+ TestServer testServer = new TestServer();
+ Thread serverThread = new Thread(new ThreadStart(testServer.StartServer));
+ serverThread.Start();
- // c = new DBus.Connection ("unix:path=/tmp/foobar");
+ connection = Bus.GetSessionBus();
+ service = Service.Get(connection, "org.freedesktop.Test");
- try {
- c = DBus.Connection.GetBus (DBus.Connection.BusType.Session);
- }
- catch (DBus.Exception e) {
- Console.Error.WriteLine ("Failed to open connection: {0}",
- e.Message);
- return;
- }
+ TestObject testObject = (TestObject) service.GetObject(typeof(TestObject), "/org/freedesktop/Test/TestObject");
- DBus.Message m = new DBus.Message ("org.freedesktop.Foo",
- "org.freedesktop.DBus.Broadcast");
-
- c.Send (m);
- c.Flush ();
+ System.Console.WriteLine(testObject.Test1("Hello"));
- IntPtr loop = g_main_loop_new (IntPtr.Zero, false);
+ //RunTests(testObject);
- g_main_loop_run (loop);
+ return 0;
+ }
- g_main_loop_unref (loop);
+ public static void RunTests(TestObject testObject)
+ {
+ System.Console.WriteLine(testObject.Test1("Hello"));
+ }
}
- internal const string GLibname = "libglib-2.0.so.0";
- internal const string GThreadname = "libgthread-2.0.so.0";
-
- [DllImport (GLibname, EntryPoint="g_main_loop_new")]
- private extern static IntPtr g_main_loop_new (IntPtr context,
- bool is_running);
+ public class TestServer
+ {
+ public Connection connection;
+ public Service service;
- [DllImport (GLibname, EntryPoint="g_main_loop_unref")]
- private extern static void g_main_loop_unref (IntPtr loop);
+ public TestServer()
+ {
+ Application.Init();
+
+ System.Console.WriteLine("Starting server...");
- [DllImport (GLibname, EntryPoint="g_main_loop_run")]
- private extern static void g_main_loop_run (IntPtr loop);
+ connection = Bus.GetSessionBus();
+ service = new Service(connection, "org.freedesktop.Test");
+ TestObject testObject = new TestObject();
+ service.RegisterObject(testObject, "/org/freedesktop/Test/TestObject");
+ }
+
+ public void StartServer()
+ {
+ Application.Run();
+ }
+ }
- [DllImport (GLibname, EntryPoint="g_main_loop_quit")]
- private extern static void g_main_loop_quit (IntPtr loop);
-
- [DllImport (GThreadname, EntryPoint="g_thread_init")]
- private extern static void g_thread_init (IntPtr vtable);
+ [Interface("org.freedesktop.Test.TestObject")]
+ public class TestObject
+ {
+ [Method]
+ public virtual int Test1(string x)
+ {
+ System.Console.WriteLine("Called: " + x);
+ return 5;
+ }
+ }
}
--- DBus.cs DELETED ---
- Previous message: dbus dbus-sharp.pc.in, NONE, 1.1 ChangeLog, 1.461, 1.462 Makefile.am,
1.18, 1.19 configure.in, 1.78, 1.79
- Next message: dbus configure.in,1.79,1.80
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the dbus-commit
mailing list