Thanks, a lot for your first-hand experience.

On 8 January 2012 20:29, ncalexan <ncalexan...@gmail.com> 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*)').

Do you have it available somewhere?

>
> 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.

:) Yes, i should start writing it. I was waiting till project will
mature enough & stabilize a bit.
and of course i am lazy.

> * NB has a simple conceptual model, but it is still not as simple as the FFI
> model.

yep. a bit more concepts, because a bit more features.

> * 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.

this statement can be applied to any FFInterface, if you declare function
with wrong types/arguments or pass wrong argument values. :)
I spent last 3 days rewriting aligment interface, and hacking opengl
glue code, and guess what:
it never crashed on me.
And yes, i saving image every time before going to run the freshly
hacked assembly code :)

> * 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.

need more data, data pls. I refined a stack-aligned interface recently, and
don't have any problems with alignment.. but sure, i maybe lack of
real-world experience ;)

> * 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.

well, you don't have to go there. Usually i takes less time to grok
assembler code in image
to find an error than trying to understand what happens in GDB.. in
text mode... ohhhhhh :)

> * 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.

Hmm.. there should be everything fine there. Trailers are not
stripping any interpreter-specific state,
just adds own on top of it.

> * 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.

consider following:

struct x k;
struct x * l = &k;
struct x ** m = &l;

"struct x" foo (k);   << push &k, because all structs are passed by reference.
"struct x * " foo (l); << push value of l = &k
"struct x **" foo (m);  << push value of m = &l

&l obviously <> &k
becasue &k points to first byte of your structure, while &l points to
first byte of _pointer_ to that structure.

usually a ** used in cases when function wants to store result on
success. It is like say:
 give me a memory location where i should store a pointer to that
structure, so you can use it later.

Unfortunately there is no way to automate that. It means that if you
owning a structure,
myStruct = NBExternalStructureSubclass new.

passing it as argument to functions which takes struct x** may be dangerous.

So, in case if function under the question wants to return a pointer
to struct back to you, you can do just following:

- change the function declaration to following:

 #( void foo ( NBExternalAddress * address ) )  "this stands for
void foo(struct **x) "

in this case NB will not push the value of address , but a place in
memory where this pointer is stored.
Function then writes a new address value there. and so you can use it
later by simply:

addr := NBExternalAddress new.
self foo: addr.
mystruct := NBExternalStructure fromPointer: addr.

and now you can access the values in struct:
mystruct x = 5 ifTrue: [...]

If function may want not only to give you address back, but also may
want to read your struct fields by occasion,
then you have no choice but to use external memory:

myStruct := MyExternalStruct new.
myStruct x: 4; y 5; ... etc..

externalSpace := NativeBoost allocate: myStruct class instanceSize.
NativeBoost memcpy: myStruct to: externalSpace size: myStruct class
instanceSize.

now, if you pass externalSpace in same way:

self foo: externalSpace

it will push an address to that address, where copy of your structure lies ;)

Now, i would like to know how you solving this with FFI.

>
> 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.
>

Now it should work fine, so no worries :)
Just remember: Communication is the key.
I am not dead, and i willing to help anyone who using NativeBoost,
So, please, send me feedback, troublesome code, or even whole image(s)
and do not hesitate to contact with me.
Because it is two way road: i helping you to make it work, you helping
me to get rid of defects and misconceptions and missing features. :)

> 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.
>



-- 
Best regards,
Igor Stasenko.

Reply via email to