diff options
author | Havoc Pennington <hp@redhat.com> | 2003-06-22 22:59:31 +0000 |
---|---|---|
committer | Havoc Pennington <hp@redhat.com> | 2003-06-22 22:59:31 +0000 |
commit | 1cc184b4a849619b56bed2be0e752fbc0fb75a29 (patch) | |
tree | 867409e28e08152147e095606e487793873dd51e | |
parent | 958805418359aca169cd363a4a3279f0fdab753c (diff) |
2003-06-22 Havoc Pennington <hp@pobox.com>
* mono/Connection.cs, mono/DBus.cs, mono/Error.cs:
Start wrapping more stuff.
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | mono/Connection.cs | 123 | ||||
-rw-r--r-- | mono/DBus.cs | 13 | ||||
-rw-r--r-- | mono/Error.cs | 29 | ||||
-rw-r--r-- | mono/Makefile.am | 6 | ||||
-rw-r--r-- | mono/Message.cs | 19 | ||||
-rw-r--r-- | mono/Test.cs | 3 |
7 files changed, 186 insertions, 12 deletions
@@ -1,5 +1,10 @@ 2003-06-22 Havoc Pennington <hp@pobox.com> + * mono/Connection.cs, mono/DBus.cs, mono/Error.cs: + Start wrapping more stuff. + +2003-06-22 Havoc Pennington <hp@pobox.com> + * mono/Message.cs: implement Message.Wrap() that ensures we only have a single C# wrapper per DBusMessage, assuming it works which it probably doesn't. diff --git a/mono/Connection.cs b/mono/Connection.cs new file mode 100644 index 00000000..f0d34eec --- /dev/null +++ b/mono/Connection.cs @@ -0,0 +1,123 @@ +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) 0) { + dbus_connection_unref (raw); + } else { + Exception e = new Exception (ref error); + error.Free (); + throw e; + } + } + + public static Connection Wrap (IntPtr ptr) { + IntPtr gch_ptr; + + gch_ptr = dbus_connection_get_data (ptr, wrapper_slot); + if (gch_ptr != (IntPtr) 0) { + 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_; + IntPtr raw { + get { + return raw_; + } + set { + if (value == raw_) + return; + + if (raw_ != (IntPtr) 0) { + IntPtr gch_ptr; + + gch_ptr = dbus_connection_get_data (raw_, + wrapper_slot); + Debug.Assert (gch_ptr != (IntPtr) 0); + + dbus_connection_set_data (raw_, wrapper_slot, + (IntPtr) 0, (IntPtr) 0); + + ((GCHandle) gch_ptr).Free (); + + dbus_connection_unref (raw_); + } + + raw_ = value; + + if (raw_ != (IntPtr) 0) { + 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) 0); + } + } + } + + ~Connection () { + raw = (IntPtr) 0; // free the native object + } + + Connection (IntPtr r) { + raw = r; + } + + // static constructor runs before any methods + static Connection () { + 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.Libname, EntryPoint="dbus_connection_open")] + private extern static IntPtr dbus_connection_open (string address, + ref Error error); + + [DllImport (DBus.Internals.Libname, EntryPoint="dbus_connection_unref")] + private extern static void dbus_connection_unref (IntPtr ptr); + + [DllImport (DBus.Internals.Libname, EntryPoint="dbus_connection_ref")] + private extern static void dbus_connection_ref (IntPtr ptr); + + [DllImport (DBus.Internals.Libname, EntryPoint="dbus_connection_allocate_data_slot")] + private extern static bool dbus_connection_allocate_data_slot (ref int slot); + + [DllImport (DBus.Internals.Libname, EntryPoint="dbus_connection_free_data_slot")] + private extern static void dbus_connection_free_data_slot (ref int slot); + + [DllImport (DBus.Internals.Libname, 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.Libname, EntryPoint="dbus_connection_get_data")] + private extern static IntPtr dbus_connection_get_data (IntPtr ptr, + int slot); + } +} diff --git a/mono/DBus.cs b/mono/DBus.cs new file mode 100644 index 00000000..1032792a --- /dev/null +++ b/mono/DBus.cs @@ -0,0 +1,13 @@ +namespace DBus { + + using System; + + public class Exception : ApplicationException { + internal Exception (ref Error error) + : base (Runtime.InteropServices.Marshal.PtrToStringAnsi (error.message)) { } + } + + public class Internals { + public const string Libname = "libdbus-1.so.0"; + } +} diff --git a/mono/Error.cs b/mono/Error.cs new file mode 100644 index 00000000..95c0193b --- /dev/null +++ b/mono/Error.cs @@ -0,0 +1,29 @@ +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.Libname, EntryPoint="dbus_error_init")] + private extern static void dbus_error_init (ref Error error); + [DllImport (DBus.Internals.Libname, EntryPoint="dbus_error_free")] + private extern static void dbus_error_free (ref Error error); + } +} diff --git a/mono/Makefile.am b/mono/Makefile.am index d81bcc28..efd61b4b 100644 --- a/mono/Makefile.am +++ b/mono/Makefile.am @@ -3,16 +3,16 @@ DESTDIR= DLLS=dbus-sharp.dll NOINST_EXES=test-dbus-sharp -DBUS_SHARP_FILES=Message.cs +DBUS_SHARP_FILES= DBus.cs Message.cs Connection.cs Error.cs TEST_DBUS_SHARP_FILES=Test.cs all: $(DLLS) $(NOINST_EXES) dbus-sharp.dll: $(DBUS_SHARP_FILES) - $(MCS) $(MCSFLAGS) --unsafe --target library -o dbus-sharp.dll --recurse '$(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 --recurse '$(TEST_DBUS_SHARP_FILES)' + $(MCS) $(MCSFLAGS) --unsafe --target exe -L . -r dbus-sharp.dll -o test-dbus-sharp $(TEST_DBUS_SHARP_FILES) clean: rm -f $(DLLS) $(NOINST_EXES) diff --git a/mono/Message.cs b/mono/Message.cs index 0e41c9ec..a6d3c092 100644 --- a/mono/Message.cs +++ b/mono/Message.cs @@ -10,6 +10,8 @@ namespace DBus { string dest_service) { // the assignment bumps the refcount raw = dbus_message_new (name, dest_service); + if (raw == (IntPtr) 0) + throw new OutOfMemoryException (); dbus_message_unref (raw); } @@ -92,34 +94,33 @@ namespace DBus { // slot used to store the C# object on the C object static int wrapper_slot = -1; - const string libname = "libdbus-1.so.0"; - [DllImport (libname, EntryPoint="dbus_message_new")] + [DllImport (DBus.Internals.Libname, EntryPoint="dbus_message_new")] private extern static IntPtr dbus_message_new (string name, string dest_service); - [DllImport (libname, EntryPoint="dbus_message_unref")] + [DllImport (DBus.Internals.Libname, EntryPoint="dbus_message_unref")] private extern static void dbus_message_unref (IntPtr ptr); - [DllImport (libname, EntryPoint="dbus_message_ref")] + [DllImport (DBus.Internals.Libname, EntryPoint="dbus_message_ref")] private extern static void dbus_message_ref (IntPtr ptr); - [DllImport (libname, EntryPoint="dbus_message_get_name")] + [DllImport (DBus.Internals.Libname, EntryPoint="dbus_message_get_name")] private extern static string dbus_message_get_name (IntPtr ptr); - [DllImport (libname, EntryPoint="dbus_message_allocate_data_slot")] + [DllImport (DBus.Internals.Libname, EntryPoint="dbus_message_allocate_data_slot")] private extern static bool dbus_message_allocate_data_slot (ref int slot); - [DllImport (libname, EntryPoint="dbus_message_free_data_slot")] + [DllImport (DBus.Internals.Libname, EntryPoint="dbus_message_free_data_slot")] private extern static void dbus_message_free_data_slot (ref int slot); - [DllImport (libname, EntryPoint="dbus_message_set_data")] + [DllImport (DBus.Internals.Libname, EntryPoint="dbus_message_set_data")] private extern static bool dbus_message_set_data (IntPtr ptr, int slot, IntPtr data, IntPtr free_data_func); - [DllImport (libname, EntryPoint="dbus_message_get_data")] + [DllImport (DBus.Internals.Libname, EntryPoint="dbus_message_get_data")] private extern static IntPtr dbus_message_get_data (IntPtr ptr, int slot); } diff --git a/mono/Test.cs b/mono/Test.cs index ffe7d0a6..e07504d7 100644 --- a/mono/Test.cs +++ b/mono/Test.cs @@ -4,6 +4,9 @@ using System; class Test { static void Main() { DBus.Message m; + DBus.Connection c; + + c = new DBus.Connection ("unix:path=/tmp/foobar"); m = new DBus.Message ("org.freedesktop.Foo", null); |