thanks sean
this is cool to see such kind of documentation emerging.

Stef

On May 20, 2010, at 9:16 PM, Sean P. DeNigris wrote:

> 
> I want to get this info into the help system and/or collaborative book, as
> similar questions pop up regularly on the lists.
> 
> I compiled every piece of info I could find.  The focus in on FFI, with
> stubs for other strategies.  Please read this *very* rough outline for
> missing info and inaccuracies:
> 
> FFI
> 
> What is FFI and what is it used for?  Calling functions in libraries outside
> of the image...
> 
> FFI, the Squeak Foreign Function Interface, is used to call functions
> located in shared libraries that are not part of the Squeak VM nor its
> plugins. It also provides means to read and write memory structures that are
> associated with the use of those shared libraries. A typical use is to
> directly invoke operating system APIs. As such, applications that use FFI
> can only be used on the platform(s) that support the particular API being
> used. C conventions are used throughout, though the external function could
> have been written by any language capable of generating object code that
> follows C conventions.  FFI is probably the easiest way to do the things it
> does. FFI is pretty fast too. Croquet uses FFI calls to OpenGL for all it's
> drawing routines.[1]
> 
> How does FFI work?
> Technically what happens is:
> * you define what the interface is - the parameters, types etc.
> * when you make the call, the FFI logic assembles the data from the Squeak
> Objects into the proper structures according to the routine calling
> conventions for your architecture, and of course manages the return values.
> So no magic but perhaps just a little assembler in the plugin to properly
> deal with all the registers and condition flags.
> 
> How do I use it?
> 
> 1. make a method (whose structure is similar to a named primitive method)
> 
> Example: 
> system: aString "name (by convention is apiXxx: e.g. apiSystem:)"
> 
>       <apicall: long 'system' (char*) module: 'libSystem.dylib'> "first line
> should be the external function specification"
>       ^self externalCallFailed.
> 
> Let's take it piece by piece:
> 
>       system: aString
>               Method name - by convention named 'apiXxx'
>       
>       <apicall: long 'system' (char*) module: 'libSystem.dylib'>
>               Function specification
>                       - should be the first line
>                       - enclosed in angle brackets: < > containing:
>                               1. Calling Convention, either apicall: (Pascal 
> convention) or cdecl: (C
> convention)
>                                       - Mac - use either one
>                                       - Unix - use cdecl
>                                       - Windows - use apical
>                               2. Return Type (see types)
>                               3. External Function Name (literal string)
>                               4. Argument Types (a literal array) 
>                               5. Module - "module: " + [filename of the 
> external library (literal
> string)] (see below).
> 
>       self externalCallFailed.
>               Failure handler
>                       - normal smalltalk code
>                       - executed if the linking to or calling the external 
> function fails
>                       - API calls don't know how to communicate failure like 
> Squeak primitives
> do, so:
>                               - it does not tell you whether the external 
> function succeeded
>                               - the most common code is simply '^self 
> externalCallFailed.'
> 
> Argument Types
>       - must be names of ExternalTypes, either:
>               - atomic types (see ExternalType class>>initializeFFIConstants 
> and
> ExternalType class>>initializeAtomicTypes):
>                       void
>                       bool
>                       byte (unsigned)
>                       sbyte (signed)
>                       ushort (16-bit unsigned)
>                       short (16-bit signed)
>                       ulong (32-bit unsigned)
>                       long (32-bit signed)
>                       ulonglong (64-bit unsigned)
>                       longlong (64-bit signed)
>                       char (unsigned)
>                       schar (signed)
>                       float (single-precision float)
>                       double (double-precision float)
> 
> Structure Types [4]
>       - subclass of ExternalStructure
>               - class>>fields that returns an array of field descriptions 
> (see below)
>                       - Example:
>                               fields
>                                       ^#((red   'byte')(green 'byte')(blue  
> 'byte'))           
>               - class>>initialize which includes "self defineFields" (which 
> must be
> called before using the class)
>       - refer to as MyExternalStructure* (to indicate that the argument or 
> return
> is a pointer to that structure)
> 
> Field description [4]
>       - 2-element array (or three but that does something else, I'm not sure
> what):
>               - first element is the field name
>               - second is the type
> 
> Mac Memory Allocation Issues [4] (not sure about this)
> 
> If you allocate external structures, those with memory outside the Squeak
> process space, you may need to increase the amount of memory that is
> reserved outside the object heap for such use. The Mac OS (9 and previous)
> needs this, other platforms may be able to dynamically get more memory from
> the OS. To see how much memory is currently reserved printIt 'Smalltalk
> extraVMMemory'. To change it, execute 'Smalltalk extraVMMemory:
> someNumberofBytes' Then save your image and quit. When you next start up,
> the amount of memory you requested will be reserved. (JMM) Note the OSX
> versions of the VM ignore extraVMMemory because the memory model for
> OS-X/unix applications is quite different.
> 
> Module Name 
> - depends on the platform
>       - Mac
>               - pre Snow Leopard: flexible, can eliminate leading lib or 
> extension e.g.
> 'libc.dylib' becomes 'libc', 'c.dylib', or 'c'
>               - Snow Leopard
>                       - file name must be exact including extension (unless 
> Info.plist is
> altered as in 'Library Location' below)
>               - With pre-mach-o VMs
>                       - For Classic applications, use 'InterfaceLib'
>                       - For Carbon libs, use 'CarbonLib'
> 
> Module Location - where the external library file lives
>       - depends on the platform
>               - Mac
>                       - pre Snow Leopard
>                               - checks VM path and common library paths
>                       - Snow Leopard
>                               - only looks in VM bundle's Resources file, you 
> must either [5]:
>                                       - store all external libraries there
>                                       - ln -s path/to/library 
> path/to/VM/Resources/library_name
>                                       - Change the VM's Info.plist 
> "SqueakPluginsBuiltInOrLocalOnly" key from
> "true" to "false."                                                            
> Caveats
>       - security
>               - malicious users could call arbitrary functions in the OS e.g. 
>  "format
> c:" from "system.dll" [7]
>               - VMs do not protect against buffer overflow from bad 
> parameters [8]:
>                       "this would require an attacker to execute arbitrary 
> Smalltalk 
>                       code on your server. Of course if they can do that they 
> own you 
>                       anyway, especially if you allow FFi or use the 
> OSProcess plugin" - John
> McIntosh
> 
> * difficulty
>       - if you make a mistake you'll not drop into the debugger but Squeak 
> will
> just crash [2]
>       - If you crash Squeak when it is running the garbage collector, then you
> know your FFI code is leaking bits into object memory [2]
> 
> What do I need to use FFI with Squeak?
> 
> You need the FFI plugin, which is included with most VM's as of Squeak 3.6
> or so.
> 
> You can also build the plugin yourself. See VMMaker.
> 
> References:
> [1] http://wiki.squeak.org/squeak/1414
> [2] http://wiki.squeak.org/squeak/2424
> [3] http://wiki.squeak.org/squeak/5716
> [4] http://wiki.squeak.org/squeak/2426
> [5]
> http://forum.world.st/squeak-dev-Alien-Squeak-FFI-issues-on-Snow-Leopard-td85608.html
> [6] http://wiki.squeak.org/squeak/5846
> [7] http://forum.world.st/FFI-Callbacks-td54056.html#a54073
> [8] http://forum.world.st/Security-td99624.html#a99635:
> 
> Other choices:
> In the fall of 2008, Alien the FFI interface (written by Cadence Design
> Systems, Inc.) was put into squeaksource:
> http://www.squeaksource.com/Alien.html. This API allows the primitive to
> call back to Smalltalk Code, and return error code information, and
> apparently is much faster due to a less complex call sequence.
>       * if you need callbacks
>       * mac-only?
> 
> Plugins - write external code and dynamically link it to the VM
>       Pros:
>               * safest - users are limited to using the functionality you 
> provide and
> can not call other external functions e.g. system rm /
>               * fast - faster than FFI
>               * you can create new functionality that doesn't exist in any 
> library
>       Cons:
>               * harder to write
>               * plugin must be distributed with the Smalltalk code - there 
> can be
> complications with platforms
> 
> Primitive method - invokes behavior in the VM or a plugin [3]
> 
> Questions:
> * why would you want to build the FFI plugin yourself?
> * api prefix or no for method names?
> * not sure about pre Snow Leopard library search
> * OSProcess - how does this fit into the bigger picture?
> * "^self externalCallFailed." or "self externalCallFailed." i.e. return self
> or return the result, or doesn't matter?
> * why would a field description have three elements?
> * Mac Memory Allocation Issues?
> -- 
> View this message in context: 
> http://forum.world.st/FFI-Documentation-tp2225148p2225148.html
> Sent from the Pharo Smalltalk mailing list archive at Nabble.com.
> 
> _______________________________________________
> Pharo-project mailing list
> [email protected]
> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project


_______________________________________________
Pharo-project mailing list
[email protected]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project

Reply via email to