GtkExtra Marshaling in C# Mono(Linux)
-
Wenn ich das richtig sehe, gibt es doch einen Widget-Konstruktor mit IntPtr als Parameter:
var sheet = GtkExtra.gtk_sheet_new(2, 2, "Test"); var widget = new Gtk.Widget(sheet); sw.Add(widget);
-
-
Ok, weiter geht's
Es war schon fast zu einfach. Habe jetzt folgenden Code zusammen "gebastelt"
namespace GtkExtraHelper { using Gtk; using System; using System.Runtime.InteropServices; public static class GtkExtra { [DllImport("libgtkextra-x11-3.0.so")] public static extern IntPtr gtk_sheet_new(uint rows, uint columns, string title); [ComVisible(true)] [Serializable] public delegate int CellActivateEventHandler(IntPtr sheet, int row, int col, IntPtr data); } }
Einen extra GtkSheet:
namespace GtkExtraHelper { using GLib; using Gtk; using System; public class GtkSheet : Gtk.Widget { public GtkSheet(uint rows, uint columns, string title) : base(GtkExtra.gtk_sheet_new(rows, columns, title)) { } [Signal("activate")] public event GtkExtra.CellActivateEventHandler Cell_Activate { add { var signal = Signal.Lookup(this, "activate"); signal.AddDelegate(value); } remove { var signal = Signal.Lookup(this, "activate"); signal.RemoveDelegate(value); } } } }
Und MainWindow:
namespace GtkExtraHelper { using Gtk; using System; public class MainWindow : Gtk.Window { public MainWindow() : base("GtkExtra-Helper") { SetDefaultSize(600, 480); var vb = new VBox(false, 0); var sw = new ScrolledWindow(null, null); vb.PackStart(sw); var sheet = new GtkSheet(20, 20, "Sheet"); sheet.Cell_Activate += HandleCell_Activate; sw.Add(sheet); Add(vb); ShowAll(); } int HandleCell_Activate (IntPtr sheet, int row, int col, IntPtr data ) { return 0; } } }
Damit versuche ich ein EventHandler umzusetzen laut Tutorial.
Ich habe es mit einem EventHandler von Gtk versucht, es hat geklappt aber ich bekomme keine Daten. Und hier bekomme ich eine Exception geworfen, die ich leider nicht nachvollziehen kann. Jedenfalls stimmt was nicht an den Parametern. Kann jemand weiter helfen? Vielen Dank!
$ mono ./GtkExtraHelper.exe Marshaling activate signal Exception in Gtk# callback delegate Note: Applications can use GLib.ExceptionManager.UnhandledException to handle the exception. System.Reflection.TargetParameterCountException: Number of parameter does not match expected count. at System.Reflection.Binder.ConvertValues (System.Object[] args, System.Reflection.ParameterInfo[] pinfo, System.Globalization.CultureInfo culture, Boolean exactMatch) [0x00000] in <filename unknown>:0 at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0 at System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) [0x00000] in <filename unknown>:0 at System.Delegate.DynamicInvokeImpl (System.Object[] args) [0x00000] in <filename unknown>:0 at System.MulticastDelegate.DynamicInvokeImpl (System.Object[] args) [0x00000] in <filename unknown>:0 at System.Delegate.DynamicInvoke (System.Object[] args) [0x00000] in <filename unknown>:0 at GLib.Signal.ClosureInvokedCB (System.Object o, GLib.ClosureInvokedArgs args) [0x00000] in <filename unknown>:0 at GLib.SignalClosure.Invoke (GLib.ClosureInvokedArgs args) [0x00000] in <filename unknown>:0 at GLib.SignalClosure.MarshalCallback (IntPtr raw_closure, IntPtr return_val, UInt32 n_param_vals, IntPtr param_values, IntPtr invocation_hint, IntPtr marshal_data) [0x00000] in <filename unknown>:0 at GLib.ExceptionManager.RaiseUnhandledException(System.Exception e, Boolean is_terminal) at GLib.SignalClosure.MarshalCallback(IntPtr raw_closure, IntPtr return_val, UInt32 n_param_vals, IntPtr param_values, IntPtr invocation_hint, IntPtr marshal_data) at Gtk.Widget.gtk_widget_show_all(IntPtr ) at Gtk.Widget.ShowAll() at GtkExtraHelper.MainWindow..ctor() at GtkExtraHelper.MainClass.Main(System.String[] args
-
Ich glaube es liegt an [Serializable]-Parameter. Kann ich jetzt aber leider überhaupt nicht nachvollziehen, wie es zusammengebaut ist.
Kann man das anders definieren? Auf die Parameter der C-Funktion abgestimmt, wie mache ich das?
-
Mach mal deine Ereignismethode statisch:
static int HandleCell_Activate (IntPtr sheet, int row, int col, IntPtr data)
GTK kann nichts mit objektorientierten Methoden anfangen (sondern kennt nur Funktionen).
-
Das ist es leider nicht, derelbe Fehler.
Hier ist Events-Handling von gtk-sharp implementiert. Ich muss GtkExtra quasi "dazu" schalten.
Ich versuche gerade anhand von Assembler-Code einen neuen Event zu bauen.
-
Es klappt soweit mit eigenem Event:
namespace GtkExtraHelper { using Gtk; using GLib; using System; using System.Runtime.InteropServices; public static class GtkExtra { public class CellActivateEventArgs : SignalArgs { private IntPtr sheet; private int row; private int column; private IntPtr data; public CellActivateEventArgs() { } public CellActivateEventArgs(IntPtr s, int r, int c, IntPtr d) { sheet = s; row = r; column = c; data = d; } public IntPtr Sheet { get { return sheet; } } public int Row { get { return row; } } public int Column { get { return column; } } public IntPtr Data { get { return data; } } } [ComVisible(true)] [Serializable] public delegate int CellActivateEventHandler(object sender,CellActivateEventArgs args); [DllImport("libgtkextra-x11-3.0.so")] public static extern IntPtr gtk_sheet_new(uint rows, uint columns, string title); } }
Aber ich bekomme keine Daten.
Da fehlt leider noch was
-
Neue Problem. Mein Event wird nicht angenommen, warum auch immer
Fehler. Was mache ich falsch?
Ein Beispiel eines Events. Von dort bekomme ich hoffentlich die Daten her.
Der Code bis jetzt:
public class EventCellActivate : Event { public IntPtr sheet { get { return System.IntPtr.Zero; } } public int Row { get { return 1; } } public int Column { get { return 1; } } public EventCellActivate(IntPtr raw) : base(raw) { } } public class CellActivateEventArgs : SignalArgs { public EventCellActivate Event { get { return (EventCellActivate)base.Args [0]; } } } [ComVisible(true)] [Serializable] public delegate int CellActivateEventHandler(object sender,CellActivateEventArgs args);
-
Falls jemand bis dahin weiter helfen kann, würde ich mich freuen.
Ich versuche erst mal mit gtkmm das Problem zu lösen. Ist vielleicht nicht gerade der beste Weg, aber wenn's funktioniert, soll es mir auch recht sein.
-
Hat sich erledigt, es geht auch direkt einen Signal zu connecten. Problem gelöst
[UnmanagedFunctionPointer(CallingConvention.StdCall)] public delegate int ActivateCellFuncPtr(IntPtr sheet,int row,int col,IntPtr data); [DllImport("libgtk-x11-2.0.so")] public static extern ulong gtk_signal_connect_full( IntPtr obj, string name, [MarshalAs(UnmanagedType.FunctionPtr)] ActivateCellFuncPtr ac_func, IntPtr unsupported, IntPtr data, IntPtr destroy_func, int object_signal, int after);