From eweitz at common-lisp.net Fri Jan 13 07:06:35 2006 From: eweitz at common-lisp.net (Edi Weitz) Date: Fri, 13 Jan 2006 08:06:35 +0100 (CET) Subject: [rdnzl-cvs] CVS update: RDNZL/CHANGELOG.txt RDNZL/ffi.lisp RDNZL/rdnzl.asd Message-ID: <20060113070635.EA60E885A1@common-lisp.net> Update of /project/rdnzl/cvsroot/RDNZL In directory common-lisp.net:/tmp/cvs-serv26247 Modified Files: CHANGELOG.txt ffi.lisp rdnzl.asd Log Message: delegate fixes (Dominic Robinson), version 0.8.0 Date: Fri Jan 13 08:06:29 2006 Author: eweitz Index: RDNZL/CHANGELOG.txt diff -u RDNZL/CHANGELOG.txt:1.3 RDNZL/CHANGELOG.txt:1.4 --- RDNZL/CHANGELOG.txt:1.3 Mon Nov 21 15:03:40 2005 +++ RDNZL/CHANGELOG.txt Fri Jan 13 08:06:28 2006 @@ -1,3 +1,8 @@ +Version 0.8.0 +2006-01-13 +Fix mechanism which releases delegate adapters (thanks to Dominic Robinson) +Updated to DLL version 0.5.0 + Version 0.7.1 2005-11-21 Updated to DLL version 0.4.1 Index: RDNZL/ffi.lisp diff -u RDNZL/ffi.lisp:1.2 RDNZL/ffi.lisp:1.3 --- RDNZL/ffi.lisp:1.2 Fri Jul 8 20:45:34 2005 +++ RDNZL/ffi.lisp Fri Jan 13 08:06:28 2006 @@ -1,7 +1,7 @@ ;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: RDNZL; Base: 10 -*- -;;; $Header: /project/rdnzl/cvsroot/RDNZL/ffi.lisp,v 1.2 2005/07/08 18:45:34 eweitz Exp $ +;;; $Header: /project/rdnzl/cvsroot/RDNZL/ffi.lisp,v 1.3 2006/01/13 07:06:28 eweitz Exp $ -;;; Copyright (c) 2004-2005, Dr. Edmund Weitz. All rights reserved. +;;; Copyright (c) 2004-2006, Dr. Edmund Weitz. All rights reserved. ;;; Redistribution and use in source and binary forms, with or without ;;; modification, are permitted provided that the following conditions @@ -331,7 +331,7 @@ (funcall (gethash index *callback-hash*) args)) (ffi-define-callable - (ReleaseDelegateAdapter ffi-void-pointer) + (ReleaseDelegateAdapter ffi-void) ((index ffi-integer)) ;; remove entry from hash table if CLR is done with it - (remhash index *callback-hash*)) \ No newline at end of file + (remhash index *callback-hash*)) Index: RDNZL/rdnzl.asd diff -u RDNZL/rdnzl.asd:1.2 RDNZL/rdnzl.asd:1.3 --- RDNZL/rdnzl.asd:1.2 Mon Nov 21 15:04:23 2005 +++ RDNZL/rdnzl.asd Fri Jan 13 08:06:28 2006 @@ -1,5 +1,5 @@ ;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: CL-USER; Base: 10 -*- -;;; $Header: /project/rdnzl/cvsroot/RDNZL/rdnzl.asd,v 1.2 2005/11/21 14:04:23 eweitz Exp $ +;;; $Header: /project/rdnzl/cvsroot/RDNZL/rdnzl.asd,v 1.3 2006/01/13 07:06:28 eweitz Exp $ ;;; Copyright (c) 2004, Dr. Edmund Weitz. All rights reserved. @@ -39,7 +39,7 @@ (defsystem #:rdnzl :serial t - :version "0.7.1" + :version "0.8.0" :components ((:file "packages") (:file "specials") (:file "util") From eweitz at common-lisp.net Fri Jan 13 07:06:39 2006 From: eweitz at common-lisp.net (Edi Weitz) Date: Fri, 13 Jan 2006 08:06:39 +0100 (CET) Subject: [rdnzl-cvs] CVS update: RDNZL/doc/index.html Message-ID: <20060113070639.09E0A885A8@common-lisp.net> Update of /project/rdnzl/cvsroot/RDNZL/doc In directory common-lisp.net:/tmp/cvs-serv26247/doc Modified Files: index.html Log Message: delegate fixes (Dominic Robinson), version 0.8.0 Date: Fri Jan 13 08:06:34 2006 Author: eweitz Index: RDNZL/doc/index.html diff -u RDNZL/doc/index.html:1.3 RDNZL/doc/index.html:1.4 --- RDNZL/doc/index.html:1.3 Mon Nov 21 15:03:43 2005 +++ RDNZL/doc/index.html Fri Jan 13 08:06:34 2006 @@ -104,7 +104,7 @@
(RUN-APROPOS-FORM)
. If you want to try this
-several times start the function in its own thread. In AllegroCL or LispWorks
+several times, start the function in its own thread. In AllegroCL or LispWorks
that'd be:
@@ -373,7 +373,7 @@
Download and installation
RDNZL together with this documentation can be downloaded from -http://weitz.de/files/RDNZL.tar.gz, the current version is 0.7.1. It +http://weitz.de/files/RDNZL.tar.gz, the current version is 0.8.0. It doesn't depend on any other Lisp libraries. The C++ source for the shared libraryRDNZL.dll
can be downloaded separately from http://weitz.de/files/RDNZL_cpp.tar.gz but you don't need this archive @@ -399,7 +399,7 @@ For questions, bug reports, feature requests, improvements, or patches please use the rdnzl-devel -mailing list. If you want to be notified about future releases +mailing list. If you want to be notified about future releases, subscribe to the rdnzl-announce mailing list. These mailing lists and the CVS repository were made available thanks to @@ -416,7 +416,7 @@ The current status for the main Win32 Common Lisp implementations is as follows:
port-acl.lisp
, port-ccl.lisp
, port-lw.lisp
, and so on. If you want to port RDNZL to
-another Lisp it should suffice to just create the corresponding
+another Lisp, it should suffice to just create the corresponding
port-xx.lisp
file for your implementation.
@@ -461,9 +461,9 @@
for the first argument of INVOKE
, PROPERTY
, and FIELD
) you can also
provide the corresponding "native" Lisp objects as long as they can be
converted to .NET objects by the function BOX
. On the other hand, if
-a RDNZL function returns a .NET object it will be automatically
+a RDNZL function returns a .NET object, it will be automatically
translated to a Lisp object by UNBOX
if possible. If a RDNZL function
-call doesn't return a result (i.e. if its return type is System.Void
)
+call doesn't return a result (i.e. if its return type is System.Void
),
then the keyword :VOID
is returned. If a NULL
object is returned,
RDNZL returns NIL
and T
as a second return value because otherwise
there'd be no difference from returning a false boolean value.
@@ -528,7 +528,7 @@
constructor based on the signature determined by args
. type
can either
be a container representing a .NET type or a string naming the type.
-If type
is a delegate type then there should be exactly one more
+If type
is a delegate type, then there should be exactly one more
argument to NEW
and it must be a Lisp closure with a corresponding
signature. This is how callbacks from .NET into Lisp are implemented. (See the second example above and look for KeyPressEventHandler
.)
@@ -560,8 +560,8 @@
Invokes the public .NET method named by the stringmethod-name
. If -object
is a container an instance method is invoked. Ifobject
is a -string the static method of the type named by this string is invoked. +object
is a container, an instance method is invoked. Ifobject
is a +string, the static method of the type named by this string is invoked.
[Accessor]
@@ -570,8 +570,8 @@
@@ -581,8 +581,8 @@
Gets or sets the public .NET property named by the string -property-name
. Ifobject
is a container an instance property is -accessed. Ifobject
is a string the static property of the type named +property-name
. Ifobject
is a container, an instance property is +accessed. Ifobject
is a string, the static property of the type named by this string is accessed.
Gets or sets the public .NET field named by the stringfield-name
. If -object
is a container an instance field is accessed. Ifobject
is a -string the static field of the type named by this string is accessed. +object
is a container, an instance field is accessed. Ifobject
is a +string, the static field of the type named by this string is accessed.
[Function]
@@ -592,7 +592,7 @@
Makes a pass-by-reference type out of
object
and returns object
. If
-object
is not a container
+object
is not a container,
it'll be boxed first. This function makes only
sense if object
is used as an argument to INVOKE
! (And after INVOKE
has been
@@ -707,7 +707,7 @@
rdnzl-error-exception condition => exception
@@ -735,13 +735,13 @@ This is boring and error-prone, so RDNZL provides two ways to make it easier for you: You can import types and you can use namespaces.
-Ifcondition
is an error of typeRDNZL-ERROR
then this function will +Ifcondition
is an error of typeRDNZL-ERROR
, then this function will return the .NET exception object that was actually raised.
-If you import a type RDNZL internally remembers its assembly-qualified
+If you import a type, RDNZL internally remembers its assembly-qualified
name and you can now use its full name (like
"System.Windows.Forms.Button"
) instead.
-If this is still too long for you you can use namespaces to further
+If this is still too long for you, you can use namespaces to further
abbreviate type names. So, if you are using the namespace
-"System.Windows.Forms"
you can just call the type "Button"
. Note that
+"System.Windows.Forms"
, you can just call the type "Button"
. Note that
this'll only work for imported types, though.
[Function]
@@ -751,13 +751,13 @@
Imports the .NET type type
, i.e. registers its name as one that can be
abbreviated (see USE-NAMESPACE
) and creates a mapping from its short
name to its assembly-qualified name (if necessary). If type
is a
-string and assembly
is NIL
then the function will try to create the
+string and assembly
is NIL
, then the function will try to create the
type from the string with the static .NET method System.Type::GetType
.
If type
is a string and assembly
is a container representing an
-assembly then instead the .NET instance method
+assembly, then instead the .NET instance method
System.Reflection.Assembly::GetType
will be used. If type
is already
-a .NET object (i.e. a container) then the function will just register
-its name. If assembly
is a true value then the name will also be
+a .NET object (i.e. a container), then the function will just register
+its name. If assembly
is a true value, then the name will also be
mapped to its assembly-qualified name. In all cases the type itself
(as a container) will be returned.
@@ -778,7 +778,7 @@
@@ -844,7 +844,7 @@
Imports all public types of the assemblyassembly
(a string or a -container). Ifassembly
is a string then the assembly is first loaded +container). Ifassembly
is a string, then the assembly is first loaded withLOAD-ASSEMBLY
. Returnsassembly
as a container.
(invoke type "IsSubclassOf" other-type)-If the symbol starts with a percent or dollar sign then it is removed +If the symbol starts with a percent or dollar, sign then it is removed and the result is a call to
PROPERTY
or FIELD
respectively:
@@ -852,7 +852,7 @@ [$textBox control] => (field control "textBox")-If the symbol contains a dot then in all three cases this'll result in +If the symbol contains a dot, then in all three cases this'll result in a static invocation where the part before the (last) dot is used as the name of the type: @@ -862,7 +862,7 @@ [$OpCodes.Switch] => (field "Opcodes" "Switch") -If the symbol starts with a plus or minus sign then this sign is replaced +If the symbol starts with a plus or minus sign, then this sign is replaced with
"add_"
or "remove_"
respectively. This is the convention used to
add or remove event handlers:
@@ -939,10 +939,10 @@
-Defines a Lisp function named by the function namelisp-name
which invokes the .NET member named by the stringdotnet-name
.member-kind
must be one of the keywords:METHOD
,:PROPERTY
, or:FIELD
and obviously determines whether a method, a property, or a field is to be invoked - the default is:METHOD
. Iftype-name
isNIL
(which is the default) an instance member is invoked, otherwisetype-name
should be a string naming a .NET type and a static member of this type is invoked instead.doc-string
, if provided, should be a string, namely the documentation string for the Lisp function which is created. Ifdoc-string
isNIL
(which is the default) a generic documentation string will be created. +Defines a Lisp function named by the function namelisp-name
which invokes the .NET member named by the stringdotnet-name
.member-kind
must be one of the keywords:METHOD
,:PROPERTY
, or:FIELD
and obviously determines whether a method, a property, or a field is to be invoked - the default is:METHOD
. Iftype-name
isNIL
(which is the default), an instance member is invoked, otherwisetype-name
should be a string naming a .NET type and a static member of this type is invoked instead.doc-string
, if provided, should be a string, namely the documentation string for the Lisp function which is created. Ifdoc-string
isNIL
(which is the default), a generic documentation string will be created.-If
dotnet-name
isNIL
(which is the default) then the name of the .NET member will be created fromlisp-name
be the following rules: -Take the symbol name oflisp-name
and if it does not consist solely of hyphens and single-case letters just return it. Otherwise remove the hyphens and downcase all letters except for the first one and those that follow a hyphen - these are upcased. If lisp-name is a list(SETF symbol)
then we usesymbol
instead oflisp-name
. Here are some examples (note that the package doesn't matter): +Ifdotnet-name
isNIL
(which is the default), then the name of the .NET member will be created fromlisp-name
be the following rules: +Take the symbol name oflisp-name
and if it does not consist solely of hyphens and single-case letters, just return it. Otherwise remove the hyphens and downcase all letters except for the first one and those that follow a hyphen - these are upcased. If lisp-name is a list(SETF symbol)
, then we usesymbol
instead oflisp-name
. Here are some examples (note that the package doesn't matter):
@@ -980,7 +980,7 @@ sure that no references to .NET objects remain in the image and finally call lisp-name
dotnet-name
SHUTDOWN-RDNZL
prior to saving or delivering.-If you restart the image or start the executable make sure to call +If you restart the image or start the executable, make sure to call
INIT-RDNZL
before accessing any RDNZL functionality. That should do the trick.@@ -993,7 +993,7 @@
@@ -1013,10 +1013,10 @@ the MOP to map .NET types to CLOS classes. I have removed this code in favor of a simpler approach because using the MOP results in a lot of overhead at runtime and doesn't work well with application -delivery. In fact, a lot of design decisions in RDNZL are based on the +delivery. In fact, a lot of the design decisions in RDNZL are based on the fact that I want to be able to easily deliver small executables. If it were just for speed and/or convenience, RDNZL would look differently.
Prepares RDNZL for delivery or image saving. After calling this function RDNZL can't be used anymore unlessINIT-RDNZL
is called -again. Ifno-gc
isNIL
(the default) a full garbage collection is +again. Ifno-gc
isNIL
(the default), a full garbage collection is also performed.-If you're concerned about speed keep in mind that calls into .NET are +If you're concerned about speed, keep in mind that calls into .NET are expensive because a lot of marshalling of arguments is happening behind the scenes and the system deploys the .NET reflection API at runtime. It is advisable to keep interaction between .NET and Lisp out @@ -1024,7 +1024,7 @@ fully in .NET.
If you want to know more about the way methods are -looked up in RDNZL read Pedro Pinto's paper +looked up in RDNZL, read Pedro Pinto's paper about the implementation of Dot-Scheme the basics of which apply to RDNZL as well.
@@ -1046,10 +1046,21 @@ used. Currently, the only way to avoid these problems with cyclic references is: "So don't do that!"
+If .NET calls back into Lisp from a "foreign" thread (one that wasn't +created by Lisp), this'll not work in some implementations. +Specifically, as +Dominic Robinson has pointed out, there might be GC issues in this +case. +See here +and here +for possible workarounds for LispWorks. +
About the name: It was pretty clear to me from the beginning that the name of the library should be "RDNZL." -However, I'm not sure what this acronym exactly stands for. Surely "L" is +However, I'm not sure what this acronym exactly stands for. Surely, "L" is for "Lisp" and "DN" is for "DotNet". The rest? You'll figure it out... :)
Acknowledgements
@@ -1063,7 +1074,7 @@Thanks to Charles A. Cox for the port of RDNZL to AllegroCL. Thanks to Vasilis Margioulas for the CLISP port. Thanks to Roger Corman for his help with the CCL port. Thanks to Franz Inc. (and particularly Jans Aasman) for supporting the development of RDNZL.
-$Header: /project/rdnzl/cvsroot/RDNZL/doc/index.html,v 1.3 2005/11/21 14:03:43 eweitz Exp $ +$Header: /project/rdnzl/cvsroot/RDNZL/doc/index.html,v 1.4 2006/01/13 07:06:34 eweitz Exp $