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>
|
2005-03-15 Mike Kestner <mkestner@novell.com>
|
||||||
|
|
||||||
* gtk/Gtk.metadata : hide TreeSortable.SetSortFunc.
|
* 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 = \
|
EXTRA_DIST = \
|
||||||
gtk-sharp.snk \
|
gtk-sharp.snk \
|
||||||
|
gapi-cdecl-insert \
|
||||||
makefile.win32 \
|
makefile.win32 \
|
||||||
AssemblyInfo.cs.in \
|
AssemblyInfo.cs.in \
|
||||||
ChangeLog \
|
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;
|
this.handler_type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[GLib.CDeclCallback]
|
||||||
delegate void RawXMLConnectFunc (IntPtr handler_name, IntPtr objekt,
|
delegate void RawXMLConnectFunc (IntPtr handler_name, IntPtr objekt,
|
||||||
IntPtr signal_name, IntPtr signal_data,
|
IntPtr signal_name, IntPtr signal_data,
|
||||||
IntPtr connect_object, int after, IntPtr user_data);
|
IntPtr connect_object, int after, IntPtr user_data);
|
||||||
|
|
|
@ -6,6 +6,7 @@ all: windows
|
||||||
|
|
||||||
windows: generated-stamp
|
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
|
$(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
|
cd glue && make -f makefile.win32
|
||||||
|
|
||||||
generated-stamp: ../generator/codegen.exe $(APIS) $(I_APIS) *.custom
|
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 System.Runtime.InteropServices;
|
||||||
using GLib;
|
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 {
|
internal class ManagedValue {
|
||||||
private class ValueHolder {
|
|
||||||
public object val;
|
|
||||||
public int ref_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
private delegate IntPtr CopyFunc (IntPtr ptr);
|
[CDeclCallback]
|
||||||
private delegate void FreeFunc (IntPtr ptr);
|
delegate IntPtr CopyFunc (IntPtr gch);
|
||||||
|
[CDeclCallback]
|
||||||
|
delegate void FreeFunc (IntPtr gch);
|
||||||
|
|
||||||
private static Hashtable pointers = new Hashtable ();
|
static CopyFunc copy;
|
||||||
private static IntPtr cur_ptr = IntPtr.Zero;
|
static FreeFunc free;
|
||||||
private static CopyFunc copy;
|
static GType boxed_type = GType.Invalid;
|
||||||
private static FreeFunc free;
|
|
||||||
private static GType boxed_type = GType.Invalid;
|
|
||||||
|
|
||||||
[DllImport("libgobject-2.0-0.dll")]
|
[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 {
|
public static GType GType {
|
||||||
get {
|
get {
|
||||||
|
@ -65,42 +54,31 @@ namespace GLib {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IntPtr Copy (IntPtr ptr)
|
static IntPtr Copy (IntPtr ptr)
|
||||||
{
|
{
|
||||||
ValueHolder holder = (ValueHolder) pointers[ptr];
|
Console.WriteLine ("Copying ManagedGValue: " + ptr);
|
||||||
holder.ref_count++;
|
GCHandle gch = (GCHandle) ptr;
|
||||||
return ptr;
|
return (IntPtr) GCHandle.Alloc (gch.Target);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Free (IntPtr ptr)
|
static void Free (IntPtr ptr)
|
||||||
{
|
{
|
||||||
ValueHolder holder = (ValueHolder) pointers[ptr];
|
Console.WriteLine ("Freeing ManagedGValue: " + ptr);
|
||||||
if (holder == null)
|
GCHandle gch = (GCHandle) ptr;
|
||||||
return;
|
gch.Free ();
|
||||||
holder.ref_count--;
|
|
||||||
if (holder.ref_count < 1)
|
|
||||||
pointers.Remove (ptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IntPtr WrapObject (object obj)
|
public static IntPtr WrapObject (object obj)
|
||||||
{
|
{
|
||||||
ValueHolder holder = new ValueHolder ();
|
Console.WriteLine ("Wrapping Object in ManagedGValue: " + obj);
|
||||||
holder.val = obj;
|
return (IntPtr) GCHandle.Alloc (obj);
|
||||||
holder.ref_count = 1;
|
|
||||||
cur_ptr = new IntPtr (((int) cur_ptr) + 1);
|
|
||||||
pointers[cur_ptr] = holder;
|
|
||||||
return cur_ptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static object ObjectForWrapper (IntPtr ptr)
|
public static object ObjectForWrapper (IntPtr ptr)
|
||||||
{
|
{
|
||||||
if (!pointers.Contains (ptr))
|
Console.WriteLine ("Getting object of ManagedGValue: " + ptr);
|
||||||
return null;
|
return ((GCHandle)ptr).Target;
|
||||||
|
|
||||||
ValueHolder holder = (ValueHolder) pointers[ptr];
|
|
||||||
return holder.val;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ all: windows
|
||||||
|
|
||||||
windows:
|
windows:
|
||||||
$(CSC) /unsafe /nowarn:0660,0661 /target:library /out:glib-sharp.dll /recurse:*.cs
|
$(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
|
cd glue && make -f makefile.win32
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
|
|
Loading…
Add table
Reference in a new issue