%|||%
&|What |'''ffidl'''|&
&|Where |http://elf.org/ffidl/|&
&|Description|Extension which allows pure Tcl [extension]s to invoke shared< >library functions without glue.< >Available for [Linux], [Windows] and [Mac OS X].< >Currently at version 0.6 .|&
&|Updated |??/2006|&
&|Contact |mailto:rec@elf.org ([Roger E Critchlow%|%Roger E. Critchlow Jr.])|&
[RM] you can find a version 0.6 at [http://rutherglen.ics.mq.edu.au/~steffen/tcltk/ffidl/doc]
(see below for details) *broken link*.
----
[ABU] 2-apr-2009 - For MacOS users, an unofficial update version 0.6.1 can be found at
* [http://www.categorifiedcoder.info/tcltk/ffidl/ffidl-0.6.1-darwin-9-univ.tar.gz] SOURCE
* [http://www.tcl.tk/starkits/ffidl0.6.1_ub.tgz] MacOS Universal Binary (tested on Leopard)
Note that the binary package listed at http://elf.org/ffidl/ does not work on Tiger/Leopard (? only for PowerPC ?)
[ABU] 22-feb-2012 - You can download a small binary package (0.6.1.1) collecting binary libraries for 3 platforms (Win/Linux/Mac).
At runtime, the right binary library will be used.
Package is numbered 0.6.1.1 since it's a small evolution of the (unofficial) 0.6.1.
Note that a little BUG has been fixed ("Ffidlrt.tcl does not work if installed in a path name with whitespaces").
Ffidl 0.6.1.1 is available here [http://irrational-numbers.googlecode.com/files/ffidl-0.6.1.1.zip]
----
[LV] Someone should contact the author to discuss version 0.6 with him.
[DAS] I have done so at the time I made 0.6 available, Roger responded that he would look at
and integrate the changes eventually.
[kostix] 21-Jan-2007: I've found 0.6 available on its official site. Probably [DAS] should further edit this page since his changes are now in the trunk.
----
[Roger E Critchlow] [mailto:rec@elf.org] has made an experimental release of ''ffidl'',
an experimental package that allows you to call C functions using pure Tcl wrappers.
You specify a function name, a library, a list of argument types, and a return type,
and Ffidl takes care of the nasty details of converting a Tcl command call into a C function call for you.
So, if you have a shared library and a specification of the entries in the library,
you can wrap the library into a Tcl extension with Ffidl and pure Tcl.
(The quotation is from the ''ffidl'' manual at [http://elf.org/ffidl/].)
''Ffidl'' supports calls in both directions between C/C++ and
Tcl, and operates on a variety of platforms.
The name, by the way, appears to stand for "Foreign Function Interface with Dynamic Loading."
[DLR] Including ffidl in the core would be a huge boost to Tcl, and specially, Tcllib, as many modules could be written in pure Tcl. Part of the success of [Mono]/[.NET] is its [P/Invoke] feature which allows it to effortlessly wrap native libraries. The Mono implementation uses (or at least used to do) ffidl at its core.
----
[Rolf Schroedter] gave a example on c.l.t on the use of ffidl
To give you an impression about the use of ffidl,
look at the following C and TCL-declarations:
--- file foo.h: ---
int foo_init( int adr, int log );
int foo_done( void );
int foo_info( FOO_INFO *infoPtr ); /* FOO_INFO is a structure */
int foo_open( const char *port );
--- file foo.tcl: ---
load ffidl05.dll
set DLL foo.dll
ffidl::callout foo_init {int int} int [ffidl::symbol $DLL foo_init]
ffidl::callout foo_done {} int [ffidl::symbol $DLL foo_done]
ffidl::callout foo_info {pointer-var} int [ffidl::symbol $DLL foo_info]
ffidl::callout foo_open {pointer-utf8} int [ffidl::symbol $DLL foo_open]
----
[[Explain [Rolf Schroedter]'s [screensaver] example in http://groups.google.com/groups?th=ec295f4a4849b362 .]]
======
#Rolf Schroedter
#German Aerospace Center
#Institute of Space Sensor Technology and Planetary Exploration
load ffidl05.dll
ffidl::callout dll_FindWindow {pointer-utf8 pointer-utf8} int [ffidl::symbol user32.dll FindWindowA]
ffidl::callout dll_FindWindowTitle {int pointer-utf8} int [ffidl::symbol user32.dll FindWindowA]
ffidl::callout dll_FindWindowClass {pointer-utf8 int} int [ffidl::symbol user32.dll FindWindowA]
ffidl::callout dll_SetWindowPos {int int int int int int int} int [ffidl::symbol user32.dll SetWindowPos]
ffidl::callout dll_SystemParametersInfo {int int pointer int} int [ffidl::symbol user32.dll SystemParametersInfoA]
proc FindWindow { class title } {
if { [string length $class] == 0 } {
dll_FindWindowTitle 0 $title
} elseif { [string length $title] == 0 } {
dll_FindWindowClass $class 0
} else {
dll_FindWindow $class $title
}
}
proc SetWindowPos { hwnd after x y cx cy {flags 0} } {
array set VAL {TOP 0 BOTTOM 1 TOPMOST -1 NOTOPMOST -2}
set iAfter $VAL([string toupper $after])
dll_SetWindowPos $hwnd $iAfter $x $y $cx $cy $flags
}
proc SetupScreenSaver { bool } {
dll_SystemParametersInfo 97 $bool 0 0 ;# SPI_SCREENSAVERRUNNING=97
}
proc exit? {} {
set answer [tk_messageBox -message "Really quit?" -type yesno -icon question]
switch -- $answer {
yes {
SetupScreenSaver 0
exit
}
no {}
}
}
proc ScreenSaver {win} {
set size(X) [winfo screenwidth .]
set size(Y) [winfo screenheight .]
toplevel $win
wm title $win "TclScreenSaver" ;# to find the window
wm overrideredirect $win true
$win configure -relief flat -bd 0
$win configure -cursor hand2 ;# Ohne cursor ???
update idletasks ;# virtually display $win, allows window to be found
set hwnd [FindWindow "" "TclScreenSaver"]
set res1 [SetWindowPos $hwnd TOPMOST 0 0 $size(X) $size(Y)] ;# ever makes full screen
set res2 [SetupScreenSaver 1]
canvas $win.c -background yellow -width $size(X) -height $size(Y) -relief flat -bd 0
pack $win.c -expand yes -fill both
focus -force $win
bind $win exit?
bind $win {}
}
wm withdraw .
ScreenSaver .scr
======
----
Per: [Rob Hegt] post on c.l.t '''Subject: solution for regaining focus from OpTcl hosted ActiveX control'''
======
load lib/ffidl05.dll
ffidl::callout dll_SetFocus {int} int [ffidl::symbol user32.dll SetFocus]
proc GrabFocus {args} {dll_SetFocus [winfo id .]}
======
Then just bind GrabFocus to some event. In the post he uses