What: ffidl Where: http://elf.org/ffidl/ http://elf.org/pub/ffidl05.zip Description: Extension which allows pure Tcl extensions to invoke shared library functions without glue. Available for Linux and Windows. Currently at version 0.5 . Updated: 02/2000 Contact: mailto:rec@elf.org (Roger E. Critchlow Jr.)
Roger E Critchlow [1] 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 [2].)
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."
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 <Key> exit? bind $win <Motion> {} } 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 <button> .
bind . <Button> +GrabFocus
Michael Jacobson ~ Also see always on top for a another example.
Michael Jacobson ~ AutoIt wrapper code using Ffidl is here [3].
ZLM ~ web2desktop includes an example of using ffidl to set the Windows desktop background.
An energetic person could use SWIG to wrap all the standard Win32api to make it accessible in a more-or-less standard way for Tcl. No one yet seems motivated to do this.
critcl provides an alternative way approach for "calling functions in arbitrary dynamic libraries" [4].