[ANN] FFI 0.1.1 (Foreign Function Interface) for Ruby 1.8.6/7 and1.9

  • Thread starter Charles Oliver Nutter
  • Start date
S

Sean O'Halpin

Eagerly awaiting your ncurses port...

I'm aiming to get a first cut out this week (just the very basics) to
get things moving, but it will take a while to get it all done,
especially the fiddly bits. I'm going to concentrate on the core
ncurses functionality. I'm not interested in panels or forms (better
done in Ruby IMHO).
Is it possible for you to document the procedure, how you go about doing
it, so one can follow that for another port, rather than be totally
lost.

Sure, as long as you don't mind long-winded stream of consciousness :)

Regards,
Sean
 
C

Charles Oliver Nutter

Sean said:
I'm aiming to get a first cut out this week (just the very basics) to
get things moving, but it will take a while to get it all done,
especially the fiddly bits. I'm going to concentrate on the core
ncurses functionality. I'm not interested in panels or forms (better
done in Ruby IMHO).


Sure, as long as you don't mind long-winded stream of consciousness :)

Oh and please, please guys, update anything that's not well-documented here:

http://kenai.com/projects/ruby-ffi/pages/Home

It's wide open...let me know if you can't edit.

- Charlie
 
N

Nit Khair

Sean said:
I'm aiming to get a first cut out this week (just the very basics) to
get things moving, but it will take a while to get it all done,
especially the fiddly bits. I'm going to concentrate on the core
ncurses functionality. I'm not interested in panels or forms (better
done in Ruby IMHO).

I am using panels and forms - *heavily*. I understand your last
statement to mean implementing p & f's in ruby itself, avoiding what
ncurses provides. Has anyone actually done that -- i would like to see
it and see how its better and if it can be reused.
 
D

Daniel DeLorme

Nit said:
ARCH = case CPU.downcase
when /i?86|x86|i86pc|powerpc/
"i386"
when /amd64|x86_64/
"x86_64"

hmm... that code is broken. "x86_64" will match the first regex and
result in "i386"
 
C

Clifford Heath

Charles said:
Actually structs are already supported!

Sorry if you see this twice, posting difficulties.

I'm having a bash at wrapping freetds. This library
has a Context struct which contains three callback
function pointers. POLS says these should look like
this:

callback :handle_message, [ :pointer, :pointer, :pointer ], :in # TDSCONTEXT, TSSSOCKET, TDSMESSAGE
callback :handle_int, [ :pointer ], :in # void*

class Context < FFI:Struct
layout \
:locale, :pointer, 0, # TDSLOCALE
:parent, :pointer, 4, # void *
:msg_handler, :handle_message, 8, # callback(TDSCONTEXT, TDSSOCKET, TDSMESSAGE)
:err_handler, :handle_message, 12, # callback(TDSCONTEXT, TDSSOCKET, TDSMESSAGE)
:int_handler, :handle_int, 16 # callback(void*)
end

Am I on the right track, or is this not possible yet?

Clifford Heath.
 
C

Charles Oliver Nutter

Clifford said:
Charles said:
Actually structs are already supported!

Sorry if you see this twice, posting difficulties.

I'm having a bash at wrapping freetds. This library
has a Context struct which contains three callback
function pointers. POLS says these should look like
this:

callback :handle_message, [ :pointer, :pointer, :pointer ], :in #
TDSCONTEXT, TSSSOCKET, TDSMESSAGE
callback :handle_int, [ :pointer ], :in # void*

class Context < FFI:Struct
layout \
:locale, :pointer, 0, # TDSLOCALE
:parent, :pointer, 4, # void *
:msg_handler, :handle_message, 8, # callback(TDSCONTEXT,
TDSSOCKET, TDSMESSAGE)
:err_handler, :handle_message, 12, # callback(TDSCONTEXT,
TDSSOCKET, TDSMESSAGE)
:int_handler, :handle_int, 16 # callback(void*)
end
Am I on the right track, or is this not possible yet?

There's no support at the moment for callbacks-in-structs, but it's just
a bug report (and ideally a patch) away :)

http://kenai.com/projects/ruby-ffi

- Charlie
 
C

Clifford Heath

Charles said:
There's no support at the moment for callbacks-in-structs, but it's just
a bug report (and ideally a patch) away :)
http://kenai.com/projects/ruby-ffi

Thanks Charlie. I registered at Kenai.com and can log in there
though only by emaill address, username login doesn't work), but
the Bugzilla instalce doesn't recognise the login details at all.
I'll try again later, in case there's a delayed processing step.
I can't see any separate registration for Bugzilla...

Clifford Heath.
 
C

Charles Oliver Nutter

Clifford said:
Thanks Charlie. I registered at Kenai.com and can log in there
though only by emaill address, username login doesn't work), but
the Bugzilla instalce doesn't recognise the login details at all.
I'll try again later, in case there's a delayed processing step.
I can't see any separate registration for Bugzilla...

I'll make sure the Kenai guys know about the problem. Thanks for giving
it a shot. If nothing else, email the dev mailing list.

- Charlie
 
L

Luc Heinrich

Thanks Charlie. I registered at Kenai.com and can log in there
though only by emaill address, username login doesn't work)

Speaking of that Kenai thing, am I the only one who think it's a =20
*major* pain in the derri=E8re to use ?

--=20
Luc Heinrich - (e-mail address removed)
 
C

Clifford Heath

Charles said:
Clifford said:
callback :handle_message, [ :poi...
class Context < FFI:Struct
layout \
:msg_handler, :handle_message, 8,
There's no support at the moment for callbacks-in-structs

While I'm on a roll, my example above creates a new type (handle_message),
and the ability to define other kinds of types similarly would be excellent.
For example, FreeTDS also has a string struct that contains a char* and a
length, and it uses that type liberally. A typedef would rock, and the above
example would just create a function-pointer typedef.

In a previous life, we implemented a generic structure pack/unpack subsystem.
It had a table for every type containing the alignment and size of that type.
Some architectures need more than one table depending on compile options, but
we supported 30 different architectures using tables whose values were filled
in by the C compiler. The rule of C don't allow re-ordering structure elements,
or at least, the require that two structures that start with the same elements
use the same alignment for those elements.

You can discover the alignment of a type by declaring a struct z { char x; TYPE y; }
and asking for offsetof(struct z, y); Mere byte-counting and padding suffices
to calculate alignment for the members of any structure. Nested structures are
padded to the largest of either the maximum alignment of the members, or some
size specific to the architecture. This can also be populated into the alignment
tables by the C compiler.

If FFI could include such a facility for Struct definitions, that would be magic,
as the current system is almost impossible to use for cross-platform support.
Unless you use the awkward templating system, of course... That requires that
you have the development versions of the target libraries when you want to gem
install a wrapper.

Just some random thoughts, anyhow. I might have time to contribute code to this
effort in December.

Clifford Heath.
 
B

brett

I get the following when I try to compile on windows - any
suggestions? Not sure what srcdir should be or where I should set it.

========================================================================

C:\ffi>gem install ffi-0.1.0.gem
Building native extensions. This could take a while...
ERROR: Error installing ffi-0.1.0.gem:
ERROR: Failed to build gem native extension.

C:/ruby/bin/ruby.exe extconf.rb install ffi-0.1.0.gem
creating Makefile

nmake

Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.

makefile(182) : fatal error U1052: file '$(srcdir)/ffi.mk' not found
Stop.


Gem files will remain installed in C:/ruby/lib/ruby/gems/1.8/gems/
ffi-0.1.0 for inspection.
Results logged to C:/ruby/lib/ruby/gems/1.8/gems/ffi-0.1.0/ext/
gem_make.out
 
C

Charles Oliver Nutter

Clifford said:
Just some random thoughts, anyhow. I might have time to contribute code
to this
effort in December.

Sounds like you've dealt with a lot of this stuff before. Can you
re-post this to the main FFI mailing list?

- Charlie
 
C

Charles Oliver Nutter

brett said:
I get the following when I try to compile on windows - any
suggestions? Not sure what srcdir should be or where I should set it.

There needs to be a pre-built gem for win32, but we haven't published
one yet. I think someone's working on getting it wired up.

- Charlie
 
L

Luis Lavena

Speaking of that Kenai thing, am I the only one who think it's a  
*major* pain in the derrière to use ?

Nop, count me on that too.

Tried to use bugzilla to provide some patches, and is a no go, only
fall back to mailing list seems the alternative.
 
P

Paul Brannan

Very cool!

I don't know how I missed this before, somehow slipped past my mental
filter (and now everything you were talking about at RubyConf starts to
make a lot more sense... :).

One question: a complaint I've had with DL is that it requires that I
specify the dynamic library that contains symbols I'm interested in. Is
this necessary with FFI? Can FFI be used to call functions in the Ruby
standard library when Ruby is not build with --enable-shared?

If so, I'd be interested in using this for Ludicrous to avoid having to
hard-code all the function pointers to the Ruby API functions I want to
call. That would mean, though, I would need FFI to be able to give me a
real function pointer (so I can pass the pointer to libjit.. I can
imagine this being useful for other cases as well).

Paul
 
S

Sean O'Halpin

Eagerly awaiting your ncurses port...

Is it possible for you to document the procedure, how you go about doing
it, so one can follow that for another port, rather than be totally
lost.

Hi,

I've just uploaded the ~very raw~ initial port of the core ncurses lib
to ruby-ffi. You can find it at:

git://github.com/seanohalpin/ffi-ncurses.git

This works with ffi-0.0.2 (which I got from the kenai project) - 0.0.1
left out typedefs for short ints.

To use:

require 'rubygems'
require 'ffi'
require 'ffi-ncurses

notes:
- example.rb shows basic usage
- to access stdscr, use the return value from NCurses.initscr
- I have not implemented any variadic functions (not supported by libffi AFAIK)
- there's also a wrapper for libdl called dlfcn.rb
- there's an experimental script (ex01-ffi-dl-stdscr.rb) which uses
dlfcn.rb to access the exported variables from the ncurses shared lib
(stdscr, curscr, etc.). This also shows how to access values returned
through pointers (see NCurses.wattr_get).

There are some rambling notes on implementation in
notes-on-ffi-curses.org. I'll tidy these up when I get some spare
time. Basically, I wrote a script
(generate-ffi-ncurses-function-signatures.rb) that mechanically
recovered the function signatures from the ncurses.h on my machine and
added some constants. I wasted a lot of time figuring out how to
access exported variables.

I've only just done a final test on OS X Tiger - haven't checked Linux
yet (should work but...)

I have not set up a project for this yet so please send any bug
reports, questions, etc. directly to me for the moment.

There are no tests - I wonder if anyone has any ideas how best to
write specs/tests for checking this kind of output?

Regards,
Sean
 
R

Rados³aw Bu³at

SSB0cmllZCB0byBydW4gYWxsIGV4YW1wbGVzIGJ1dCBubyBvbmUgd29ya2VkLiBJdCBwcmludHMg
dG9ucyBvZjoKL3Vzci9saWIvcnVieS9nZW1zLzEuOC9nZW1zL2ZmaS0wLjEuMS9saWIvZmZpL2Zm
aS5yYjoyMzI6IHdhcm5pbmc6Cmluc3RhbmNlIHZhcmlhYmxlIEBmZmlfY29udmVudGlvbiBub3Qg
aW5pdGlhbGl6ZWQKCmFuZCBsYXN0IGxpbmU6CmV4YW1wbGUtcHJpbnR3LXZhcmlhZGljLnJiOjc6
IHVuZGVmaW5lZCBtZXRob2QgYHByaW50dycgZm9yCk5DdXJzZXM6TW9kdWxlIChOb01ldGhvZEVy
cm9yKQoKLS0gClBvemRyYXdpYW0KClJhZG9zs2F3IEJ1s2F0Cmh0dHA6Ly9yYWRhcmVrLmpvZ2dl
ci5wbCAtIG3zaiBibG9nCg==
 
S

Sean O'Halpin

my wrapper requires ffi-0.2.0
I notice I got the version number wrong in my earlier post (I said
0.0.2) - apologies for any confusion caused.

Regards,
Sean
 
C

Charles Oliver Nutter

Sean said:
I've just uploaded the ~very raw~ initial port of the core ncurses lib
to ruby-ffi. You can find it at:

git://github.com/seanohalpin/ffi-ncurses.git

This works with ffi-0.0.2 (which I got from the kenai project) - 0.0.1
left out typedefs for short ints.

Very cool :) The early examples worked fine in JRuby but this one seems
to blow up in MemoryPointer. I'll make sure wmeissner knows about it.

I know he's taken a step back from adding new features in 0.2.0 to make
sure both JRuby and ruby-ffi are compatible again. Hopefully 0.2.0 will
be out soon along with JRuby 1.1.6.

- Charlie
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,756
Messages
2,569,534
Members
45,007
Latest member
OrderFitnessKetoCapsules

Latest Threads

Top