[Pharo-project] Best way for FFI in Pharo

Mariano Martinez Peck marianopeck at gmail.com
Sun Jan 8 17:33:40 EST 2012


On Sun, Jan 8, 2012 at 11:26 PM, Schwab,Wilhelm K <bschwab at anest.ufl.edu>wrote:

>  Why do it (automated or not) 2000 times when it can be done once?
>

I don't understand. Why should I need to change the module name so
frequently?  I have been working with squeakDBX since 4 years and we never
needed to change it.


> Think of the wasted time and change log bloat.  Would you like to do it
> every time you move from Windows to Linux and back?
>

I don't understand why you say you should change that when moving from one
OS to another one. I think you may have design issue, not FFI. With DBXTalk
we have the superclass PharoOpenDBX, with has all the openDBX api with
methods ^  self subclassResponsability. That's to mark the API. Then we
have 2 subclasses, OpenDBXUnix and OpenDBXWindows. And then OpenDBXMac
which is subclass from the Unix one but doesn't change or add anything so
far.
Then we have a Current (singleton) stored in a class variable and a class
side initialize that does

ffiImplementationForOS
    | platformName |
    platformName := Smalltalk os platformName.
    platformName = 'Win32' ifTrue:[ ^OpenDBXWin32 basicNew initialize].
    platformName = 'unix' ifTrue:[ ^OpenDBXUnix basicNew initialize].
    platformName = 'Mac OS' ifTrue:[ ^OpenDBXMacOSX basicNew initialize].
    self error: 'Cannot identify platform'.

And that's all. We never need to change anything.  The only thing you
should care is if moving the same image from one OS to another one then you
have to reinitialize this class variable.  Or...you could add it to startUp
list if you want.

Cheers


> Say it once.  The superiority of #moduleName is clear.
>
>
>
>   ------------------------------
> *From:* pharo-project-bounces at lists.gforge.inria.fr [
> pharo-project-bounces at lists.gforge.inria.fr] on behalf of Mariano
> Martinez Peck [marianopeck at gmail.com]
> *Sent:* Sunday, January 08, 2012 4:29 PM
>
> *To:* Pharo-project at lists.gforge.inria.fr
> *Subject:* Re: [Pharo-project] Best way for FFI in Pharo
>
>
>
> On Sun, Jan 8, 2012 at 10:13 PM, Schwab,Wilhelm K <bschwab at anest.ufl.edu>wrote:
>
>>  Agreed, except for thinking that changing all of the module names is
>> not a big deal :)
>>
>
> Why not? how many smalltalk lines of code do you think it could take to
> automate that? ;)
>
>
>
>>    An external library subclass is the way to go.  I know this already
>> exists in FFI, but the evolving chapter on Spock does not mention it - it
>> should not only mention it, but recommend it, IMHO.
>>
>> Stef, does it make sense yet?
>>
>>
>>
>>
>>   ------------------------------
>> *From:* pharo-project-bounces at lists.gforge.inria.fr [
>> pharo-project-bounces at lists.gforge.inria.fr] on behalf of Mariano
>> Martinez Peck [marianopeck at gmail.com]
>> *Sent:* Sunday, January 08, 2012 3:52 PM
>>
>> *To:* Pharo-project at lists.gforge.inria.fr
>> *Subject:* Re: [Pharo-project] Best way for FFI in Pharo
>>
>>
>>
>> On Sun, Jan 8, 2012 at 9:25 PM, Stéphane Ducasse <
>> stephane.ducasse at inria.fr> wrote:
>>
>>> can you give an example that I understand
>>> "One thing I strongly recommend is to favor #moduleName over pragmas
>>> listing the library - imagine changing 2000+ GSL calls if the library name
>>> changes =:0 "
>>>
>>>
>> Bill:  that already exists in FFI.
>> Stef: what Bill says is that if you bind to a specific library you have
>> to put its library name in each method that calls a ffi function. Example
>> of DBX:
>>
>> apiErrorType: handle number: err
>>     "int odbx_error_type( odbx_t*, int )"
>>     <cdecl: long 'odbx_error_type' (ulong long) module: 'opendbx'>
>>     ^ self externalCallFailed
>>
>> ----
>>
>> apiInitialize: handle backend: backend host: host port: port
>>     "long odbx_init(odbx_t**, char*, char*, char*)"
>>     <cdecl: long 'odbx_init' (ulong* char* char* char*) module: 'opendbx
>> '>
>>     ^self externalCallFailed
>>
>> ---
>>
>> xxx
>>
>> ---
>>
>> Notice the "module: 'opendbx"
>> So...if now the library is renamed or whatever, you have to change all
>> methods. But I don't think this is a real big deal. There are much worst
>> things.
>>
>> Finaly, I copy paste an answer from Andreas from a previous thread:
>>
>>
>> *The Right Way to do this is to have a subclass of ExternalLibrary and
>> implement the class-side method #moduleName along the lines of:
>>
>> MyLibrary class>>moduleName
>>  "Answer the module name to use for this library"
>>  Smalltalk platformName = 'Win32' ifTrue:[^'MyLibrary32.dll'].
>>  Smalltalk platformName = 'unix' ifTrue:[
>>     "check various locations and versions"
>>     #('/usr/lib/libMyLibrary.so'
>>       '/usr/lib/libMyLibrary.so.1'
>>       '/usr/lib/libMyLibrary.so.2'
>>       '/usr/share/libMyLibrary.so.1'
>>       '/usr/share/libMyLibrary.so.2'*
>> *) do:[:location|
>>          (FileDirectory fileExists: location) ifTrue:[^location].
>>     ].
>>     ^self error:'MyLibrary is not installed'
>>   ].
>> *
>> *
>>  *
>>
>>>  Tx
>>>
>>> On Jan 8, 2012, at 9:18 PM, Schwab,Wilhelm K wrote:
>>>
>>> > Stef,
>>> >
>>> > Absent the NB experience, +1 to the comments below.  FFI has pretty
>>> much "just worked" for me.  We need double arrays.  Callbacks would be
>>> great.  One thing I strongly recommend is to favor #moduleName over pragmas
>>> listing the library - imagine changing 2000+ GSL calls if the library name
>>> changes =:0  It makes a LOT more sense to have a class per library, and
>>> that class knows the name to use.  That's all the more true when one
>>> considers code such as ODBC that can run on multiple platforms with
>>> different names.  #moduleName can test the OS and answer the correct name.
>>> >
>>> > Bill
>>> >
>>> >
>>> > ________________________________________
>>> > From: pharo-project-bounces at lists.gforge.inria.fr [
>>> pharo-project-bounces at lists.gforge.inria.fr] on behalf of Stéphane
>>> Ducasse [stephane.ducasse at inria.fr]
>>> > Sent: Sunday, January 08, 2012 2:16 PM
>>> > To: Pharo-project at lists.gforge.inria.fr
>>> > Subject: Re: [Pharo-project] Best way for FFI in Pharo
>>> >
>>> > thanks for the feedback.
>>> > We will come back you soon :)
>>> > Because we should get FFI and NativeBoost fully working :).
>>> >
>>> > Stef
>>> >
>>> > On Jan 8, 2012, at 7:29 PM, ncalexan wrote:
>>> >
>>> >>
>>> >> fstephany wrote
>>> >>>
>>> >>> I'm also a bit lost between all the different options (plugins,
>>> >>> NativeBoost, FFI, Alien).
>>> >>>
>>> >>
>>> >> I also found this confusing, so let me tell my recent experience and
>>> my
>>> >> conclusion.
>>> >>
>>> >> I have written bindings to the SDL game programming library for use
>>> with
>>> >> Pharo.  SDL is cross-platform, and I want to support Mac (most of
>>> all),
>>> >> Windows (one must), and Linux (if I must).  As far as I can tell,
>>> Alien is
>>> >> not cross-platform and not maintained, so I have not spent time
>>> >> investigating it.
>>> >>
>>> >> Following Igor Stasenko's OpenGLSpecs package, I wrote an SDLSpecs
>>> package
>>> >> which parses the relevant C header files and then writes either an NB
>>> or FFI
>>> >> callout class tree.  I need to define a few structures, make a class
>>> pool
>>> >> with some constants, and then define lots of callouts, many of which
>>> take
>>> >> references to structures (like 'foo(struct x*)').
>>> >>
>>> >> I was able to make both work, more or less, on my Macbook Pro, using
>>> stock
>>> >> Pharo 1.3 images and Igor's NBCog.app.
>>> >>
>>> >> I found NB to be a nicer programmer experience but I found that the
>>> FFI just
>>> >> works.  There are a lot of gratuitous differences, but:
>>> >>
>>> >> * NB requires a VM compiled with a separate plugin (that I built from
>>> source
>>> >> with no trouble -- Igor has done splendid work with CMakeVMMaker).
>>> >> * NB should be faster than the FFI at pretty much everything, but I
>>> can't
>>> >> say since I haven't measured.
>>> >> * NB has useful primitives for determining if your external objects
>>> are
>>> >> still valid and for determining the current operating system (I
>>> intend to
>>> >> use these even if I don't use NB).
>>> >> * NB has very few tests and examples and essentially no documentation.
>>> >> * NB has a simple conceptual model, but it is still not as simple as
>>> the FFI
>>> >> model.
>>> >> * NB uses variableByteClasses to great advantage -- this is very cool.
>>> >>
>>> >> * NB makes it easy to crash your image, since you are evaluating
>>> native code
>>> >> in image.
>>> >> * NB is still, to my eye, raw and untested on Mac.  I had problems
>>> with
>>> >> stack alignments in bizarre places, and NB's interaction with garbage
>>> >> collection basically ended my attempts to use it.
>>> >> * NB is basically impossible to debug if you aren't very strong with
>>> x86
>>> >> assembly (I'm not even strong with x86 assembly), and the stack
>>> >> manipulations rendered GDB pretty much useless for me.
>>> >> * NB does not integrate well with the Pharo tools -- I think the
>>> >> MethodTrailers are screwing up references, implementors, and source
>>> views,
>>> >> but I haven't investigated.
>>> >> * NB does not seem to support indirections very easily -- I struggled
>>> to
>>> >> understand how to interface to foreign C functions with specs like
>>> >> 'foo(struct x)', 'foo(struct x *)' and 'foo(struct x **)', and
>>> eventually
>>> >> gave up.
>>> >>
>>> >> I wanted to help Igor with the NB project, but the NB-OpenGL Mac
>>> bindings
>>> >> crash horribly for me, and although I was able to fix them, it I just
>>> don't
>>> >> hack enough x86 assembly to figure out all the tricks Igor is doing.
>>>  The
>>> >> thought of making it all work on 3 platforms, and fix all the tool
>>> >> integration, was just too much for me.
>>> >>
>>> >> In conclusion, I prefer the FFI.  It is old, cross platform, well
>>> tested,
>>> >> somewhat documented, and reliable.  I think Igor has done some
>>> amazing work
>>> >> and I do not want to bash his project (and certainly not his code --
>>> the
>>> >> man's a magician) but the fancy features are not necessary for my
>>> project.
>>> >>
>>> >>
>>> >> fstephany wrote
>>> >>>
>>> >>> Will this interface handle callbacks ?
>>> >>>
>>> >>
>>> >> I do not need callbacks so cannot speak to this issue.
>>> >>
>>> >> Yours,
>>> >> Nick Alexander
>>> >>
>>> >> --
>>> >> View this message in context:
>>> http://forum.world.st/Best-way-for-FFI-in-Pharo-tp4275467p4276356.html
>>> >> Sent from the Pharo Smalltalk mailing list archive at Nabble.com.
>>> >>
>>> >
>>> >
>>> >
>>>
>>>
>>>
>>
>>
>> --
>> Mariano
>> http://marianopeck.wordpress.com
>>
>>
>
>
> --
> Mariano
> http://marianopeck.wordpress.com
>
>


-- 
Mariano
http://marianopeck.wordpress.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.pharo.org/pipermail/pharo-dev_lists.pharo.org/attachments/20120108/235a7211/attachment-0001.html>


More information about the Pharo-dev mailing list