2005-03-23 Mike Kestner <mkestner@novell.com>
* gapi-cdecl-insert : a little perl script to insert modopts * Makefile.am : dist the new script. for cdecl callback delegates on win32. * glade/makefile.win32 : use gapi-cdecl-insert * glade/XML.custom : add [GLib.CDeclCallback] to RawXMLConnectFunc. * glib/makefile.win32 : use gapi-cdecl-insert * glib/CDeclCallbackAttribute.cs : new attr to tag delegates with that will be invoked from native code. We have to mangle the il with a modopt otherwise they are stdcall'd. * glib/ManagedValue.cs : add [GLib.CDeclCallback] to Copy/Free. switch to using GCHandles instead of the current IntPtr hack. svn path=/trunk/gtk-sharp/; revision=42168
This commit is contained in:
parent
415773f269
commit
ac4cc59206
8 changed files with 125 additions and 42 deletions
14
ChangeLog
14
ChangeLog
|
@ -1,3 +1,17 @@
|
|||
2005-03-23 Mike Kestner <mkestner@novell.com>
|
||||
|
||||
* gapi-cdecl-insert : a little perl script to insert modopts
|
||||
* Makefile.am : dist the new script.
|
||||
for cdecl callback delegates on win32.
|
||||
* glade/makefile.win32 : use gapi-cdecl-insert
|
||||
* glade/XML.custom : add [GLib.CDeclCallback] to RawXMLConnectFunc.
|
||||
* glib/makefile.win32 : use gapi-cdecl-insert
|
||||
* glib/CDeclCallbackAttribute.cs : new attr to tag delegates with
|
||||
that will be invoked from native code. We have to mangle the il
|
||||
with a modopt otherwise they are stdcall'd.
|
||||
* glib/ManagedValue.cs : add [GLib.CDeclCallback] to Copy/Free.
|
||||
switch to using GCHandles instead of the current IntPtr hack.
|
||||
|
||||
2005-03-15 Mike Kestner <mkestner@novell.com>
|
||||
|
||||
* gtk/Gtk.metadata : hide TreeSortable.SetSortFunc.
|
||||
|
|
|
@ -2,6 +2,7 @@ SUBDIRS = sources generator parser glib pango atk gdk gtk glade art gnomevfs gno
|
|||
|
||||
EXTRA_DIST = \
|
||||
gtk-sharp.snk \
|
||||
gapi-cdecl-insert \
|
||||
makefile.win32 \
|
||||
AssemblyInfo.cs.in \
|
||||
ChangeLog \
|
||||
|
|
58
gapi-cdecl-insert
Executable file
58
gapi-cdecl-insert
Executable file
|
@ -0,0 +1,58 @@
|
|||
#!/usr/bin/perl
|
||||
#
|
||||
# gapi-cdecl-insert : Inserts il into an assembly for CDecl callback delegates.
|
||||
#
|
||||
# Authors: Mike Kestner <mkestner@novell.com>
|
||||
#
|
||||
# Copyright (c) 2005 Novell, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2 of the GNU General Public
|
||||
# License as published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public
|
||||
# License along with this program; if not, write to the
|
||||
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
# Boston, MA 02111-1307, USA.
|
||||
|
||||
die "Usage: gapi-cdecl-insert [--keyfile=<file>] <assembly_path>\n" if ($ARGV > 2);
|
||||
foreach $arg (@ARGV) {
|
||||
if ($arg =~ /--keyfile=(.*)/) {
|
||||
$key = $1;
|
||||
} elsif (-e $arg) {
|
||||
$assembly = $arg;
|
||||
} else {
|
||||
die "Usage: gapi-cdecl-insert [--keyfile=<file>] <assembly_path>\n";
|
||||
}
|
||||
}
|
||||
|
||||
if ($assembly =~ /(.*)\.dll/) {
|
||||
$basename = $1;
|
||||
`ildasm $assembly /out:$basename.raw`;
|
||||
open(INFILE, $basename . ".raw") || die "Couldn't open $basename.raw\n";
|
||||
open(OUTFILE, "> $basename.il") || die "Couldn't open $basename.il\n";
|
||||
while ($line = <INFILE>) {
|
||||
$insert = 1 if ($line =~ /\.custom instance void .*GLib\.CDeclCallbackAttribute/);
|
||||
|
||||
if ($insert && $line =~ /(.*)\s+(Invoke\(.*)/) {
|
||||
print OUTFILE "$1 modopt([mscorlib]System.Runtime.CompilerServices.CallConvCdecl) $2";
|
||||
$insert = 0;
|
||||
next;
|
||||
}
|
||||
print OUTFILE $line;
|
||||
}
|
||||
`ilasm /DLL /QUIET $basename.il`;
|
||||
`sn -R $assembly gtk-sharp.snk` if ($key);
|
||||
unlink "$basename.raw";
|
||||
unlink "$basename.il";
|
||||
unlink "$basename.res";
|
||||
} else {
|
||||
print "This script only works for dlls.\nUsage: gapi-cdecl-insert [--keyfile=<file>] <dll_path>\n";
|
||||
}
|
||||
|
||||
|
|
@ -175,6 +175,7 @@
|
|||
this.handler_type = type;
|
||||
}
|
||||
|
||||
[GLib.CDeclCallback]
|
||||
delegate void RawXMLConnectFunc (IntPtr handler_name, IntPtr objekt,
|
||||
IntPtr signal_name, IntPtr signal_data,
|
||||
IntPtr connect_object, int after, IntPtr user_data);
|
||||
|
|
|
@ -6,6 +6,7 @@ all: windows
|
|||
|
||||
windows: generated-stamp
|
||||
$(CSC) /unsafe /nowarn:0660,0661 /target:library /r:../glib/glib-sharp.dll /r:../pango/pango-sharp.dll /r:../atk/atk-sharp.dll /r:../gdk/gdk-sharp.dll /r:../gtk/gtk-sharp.dll /out:$(ASSEMBLY) /recurse:*.cs
|
||||
../gapi-cdecl-insert --keyfile=gtk-sharp.snk glade-sharp.dll
|
||||
cd glue && make -f makefile.win32
|
||||
|
||||
generated-stamp: ../generator/codegen.exe $(APIS) $(I_APIS) *.custom
|
||||
|
|
29
glib/CDeclCallbackAttribute.cs
Normal file
29
glib/CDeclCallbackAttribute.cs
Normal file
|
@ -0,0 +1,29 @@
|
|||
// CDeclCallbackAttribute.cs
|
||||
//
|
||||
// Author: Mike Kestner <mkestner@ximian.com>
|
||||
//
|
||||
// Copyright (c) 2005 Novell, Inc.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of version 2 of the Lesser GNU General
|
||||
// Public License as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this program; if not, write to the
|
||||
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
// Boston, MA 02111-1307, USA.
|
||||
|
||||
|
||||
namespace GLib {
|
||||
|
||||
using System;
|
||||
|
||||
public sealed class CDeclCallbackAttribute : Attribute
|
||||
{
|
||||
}
|
||||
}
|
|
@ -25,30 +25,19 @@ namespace GLib {
|
|||
using System.Runtime.InteropServices;
|
||||
using GLib;
|
||||
|
||||
// FIXME:
|
||||
// This used to use GCHandles, but I rewrote it to debug
|
||||
// some odd interactions. Since the boxed code in GLib is designed
|
||||
// to not interact directly with the pointers, just using our own
|
||||
// arbitrary pointer values is fine. Still, it might be useful
|
||||
// to use GCHandle later on.
|
||||
|
||||
internal class ManagedValue {
|
||||
private class ValueHolder {
|
||||
public object val;
|
||||
public int ref_count;
|
||||
}
|
||||
|
||||
private delegate IntPtr CopyFunc (IntPtr ptr);
|
||||
private delegate void FreeFunc (IntPtr ptr);
|
||||
[CDeclCallback]
|
||||
delegate IntPtr CopyFunc (IntPtr gch);
|
||||
[CDeclCallback]
|
||||
delegate void FreeFunc (IntPtr gch);
|
||||
|
||||
private static Hashtable pointers = new Hashtable ();
|
||||
private static IntPtr cur_ptr = IntPtr.Zero;
|
||||
private static CopyFunc copy;
|
||||
private static FreeFunc free;
|
||||
private static GType boxed_type = GType.Invalid;
|
||||
static CopyFunc copy;
|
||||
static FreeFunc free;
|
||||
static GType boxed_type = GType.Invalid;
|
||||
|
||||
[DllImport("libgobject-2.0-0.dll")]
|
||||
private static extern IntPtr g_boxed_type_register_static (IntPtr typename, CopyFunc copy_func, FreeFunc free_func);
|
||||
static extern IntPtr g_boxed_type_register_static (IntPtr typename, CopyFunc copy_func, FreeFunc free_func);
|
||||
|
||||
public static GType GType {
|
||||
get {
|
||||
|
@ -65,42 +54,31 @@ namespace GLib {
|
|||
}
|
||||
}
|
||||
|
||||
public static IntPtr Copy (IntPtr ptr)
|
||||
static IntPtr Copy (IntPtr ptr)
|
||||
{
|
||||
ValueHolder holder = (ValueHolder) pointers[ptr];
|
||||
holder.ref_count++;
|
||||
return ptr;
|
||||
Console.WriteLine ("Copying ManagedGValue: " + ptr);
|
||||
GCHandle gch = (GCHandle) ptr;
|
||||
return (IntPtr) GCHandle.Alloc (gch.Target);
|
||||
}
|
||||
|
||||
public static void Free (IntPtr ptr)
|
||||
static void Free (IntPtr ptr)
|
||||
{
|
||||
ValueHolder holder = (ValueHolder) pointers[ptr];
|
||||
if (holder == null)
|
||||
return;
|
||||
holder.ref_count--;
|
||||
if (holder.ref_count < 1)
|
||||
pointers.Remove (ptr);
|
||||
Console.WriteLine ("Freeing ManagedGValue: " + ptr);
|
||||
GCHandle gch = (GCHandle) ptr;
|
||||
gch.Free ();
|
||||
}
|
||||
|
||||
public static IntPtr WrapObject (object obj)
|
||||
{
|
||||
ValueHolder holder = new ValueHolder ();
|
||||
holder.val = obj;
|
||||
holder.ref_count = 1;
|
||||
cur_ptr = new IntPtr (((int) cur_ptr) + 1);
|
||||
pointers[cur_ptr] = holder;
|
||||
return cur_ptr;
|
||||
Console.WriteLine ("Wrapping Object in ManagedGValue: " + obj);
|
||||
return (IntPtr) GCHandle.Alloc (obj);
|
||||
}
|
||||
|
||||
public static object ObjectForWrapper (IntPtr ptr)
|
||||
{
|
||||
if (!pointers.Contains (ptr))
|
||||
return null;
|
||||
|
||||
ValueHolder holder = (ValueHolder) pointers[ptr];
|
||||
return holder.val;
|
||||
Console.WriteLine ("Getting object of ManagedGValue: " + ptr);
|
||||
return ((GCHandle)ptr).Target;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ all: windows
|
|||
|
||||
windows:
|
||||
$(CSC) /unsafe /nowarn:0660,0661 /target:library /out:glib-sharp.dll /recurse:*.cs
|
||||
../gapi-cdecl-insert --keyfile=gtk-sharp.snk glib-sharp.dll
|
||||
cd glue && make -f makefile.win32
|
||||
|
||||
clean:
|
||||
|
|
Loading…
Add table
Reference in a new issue