# Ruby FFI port

**URL:** <https://www.ruby-forum.com/t/ruby-ffi-port/204843>\
**Category:** IronRuby\
**Created:** [March 23, 2011, 5:41am UTC](https://www.ruby-forum.com/t/ruby-ffi-port/204843 "2011-03-23T05:41:05Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![luislavena](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/0ea827/32.png) [@luislavena](https://www.ruby-forum.com/u/luislavena)\
**Post date:** [March 23, 2011, 5:41am UTC](https://www.ruby-forum.com/t/ruby-ffi-port/204843/1 "2011-03-23T05:41:05Z")

</div>

Alright, I have a hankering again to port Ruby FFI ;).

One question: should the port be written in pure Ruby, or should this be  
a  
C# library in the same vein as YAML (IronRuby.Libraries.Yaml)? I was  
leaning towards the latter, where I would branch from  
IronLanguages/Main,  
adding a _Libraries.FFI_ folder beside _Libraries.Yaml_.

Cheers,

-Charles

---

<div class="post-metadata">

**Author:** ![valdar](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/b5a626/32.png) [@valdar](https://www.ruby-forum.com/u/valdar)\
**Post date:** [March 23, 2011, 7:14am UTC](https://www.ruby-forum.com/t/ruby-ffi-port/204843/2 "2011-03-23T07:14:08Z")

</div>

It would be easier to write the core implementation as regular C#  
library (i.e. not IronRuby.Libraries.\*) and write the public API in Ruby  
that would internally call to that library.  
The Ruby file could call load\_assembly ‘CoreFFI.dll’ and then use the  
classes defined there.

This way you don’t even need to include the code to IronRuby main repo,  
it could be a separate gem.

Tomas

From: removed\_email\_address@domain.invalid  
[[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)] On Behalf Of Charles  
Strahan  
Sent: Tuesday, March 22, 2011 6:30 PM  
To: removed\_email\_address@domain.invalid  
Subject: [Ironruby-core] Ruby FFI port

Alright, I have a hankering again to port Ruby FFI ;).

One question: should the port be written in pure Ruby, or should this be  
a C# library in the same vein as YAML (IronRuby.Libraries.Yaml)? I was  
leaning towards the latter, where I would branch from  
IronLanguages/Main, adding a Libraries.FFI folder beside Libraries.Yaml.

Cheers,

-Charles

---

<div class="post-metadata">

**Author:** ![valdar](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/b5a626/32.png) [@valdar](https://www.ruby-forum.com/u/valdar)\
**Post date:** [March 23, 2011, 7:16am UTC](https://www.ruby-forum.com/t/ruby-ffi-port/204843/3 "2011-03-23T07:16:38Z")

</div>

Another idea… what about starting from [ffi · GitHub](http://github.com/ffi) and  
replacing the C extension with C# code?  
Not sure if it will work but it’s at least worth looking at. Or perhaps  
you can also look at what JRuby is doing.

Tomas

From: removed\_email\_address@domain.invalid  
[[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)] On Behalf Of Charles  
Strahan  
Sent: Tuesday, March 22, 2011 6:30 PM  
To: removed\_email\_address@domain.invalid  
Subject: [Ironruby-core] Ruby FFI port

Alright, I have a hankering again to port Ruby FFI ;).

One question: should the port be written in pure Ruby, or should this be  
a C# library in the same vein as YAML (IronRuby.Libraries.Yaml)? I was  
leaning towards the latter, where I would branch from  
IronLanguages/Main, adding a Libraries.FFI folder beside Libraries.Yaml.

Cheers,

-Charles

---

<div class="post-metadata">

**Author:** ![valdar](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/b5a626/32.png) [@valdar](https://www.ruby-forum.com/u/valdar)\
**Post date:** [March 24, 2011, 9:10pm UTC](https://www.ruby-forum.com/t/ruby-ffi-port/204843/4 "2011-03-24T21:10:51Z")

</div>

> Another idea what about starting from [ffi · GitHub](http://github.com/ffi) and replacing  
> the C extension with C# code?

That’s a great idea, Tomas. I’ll need some immediate gratification to  
keep  
me from getting discouraged; porting the C funcs piecemeal sounds like a  
good way to get _something_ working. I’ve forked  
FFI[https://github.com/cstrahan/iron-ffi](https://github.com/cstrahan/iron-ffi)- I’ll try to lay out a  
foundation tonight.

-Charles

On Wed, Mar 23, 2011 at 12:29 AM, Tomas M. \<

---

<div class="post-metadata">

**Author:** ![valdar](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/b5a626/32.png) [@valdar](https://www.ruby-forum.com/u/valdar)\
**Post date:** [March 24, 2011, 9:54pm UTC](https://www.ruby-forum.com/t/ruby-ffi-port/204843/5 "2011-03-24T21:54:06Z")

</div>

I’ve successfully built the FFI gem on my Win7 x64 machine, but the  
specs  
currently fail:

_E:/Source/ffi/lib/ffi/library.rb:147:in `attach\_function’: Function  
‘strdup’ not_

- found in [msvcrt.dll] (FFI::NotFoundError)\*
- 

```
   from E:/Source/ffi/spec/ffi/strptr_spec.rb:33:in 

```

`module:StrPtr’\*

This is a known problem, but it hasn’t been fixed yet:

> **[ruby-ffi - Google Groups](https://groups.google.com/g/ruby-ffi/c/xAdmtXShWWI)**

> Thats just a symbol lookup problem. All the traditional libc symbols  
> in msvcrt.dll have an underscore prepended, so that test should have a  
> special case for win32 in it.

My first goal is to fix any failing specs. Any help would be  
appreciated.

-Charles

On Thu, Mar 24, 2011 at 1:58 PM, Charles S. \<

---

<div class="post-metadata">

**Author:** ![valdar](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/b5a626/32.png) [@valdar](https://www.ruby-forum.com/u/valdar)\
**Post date:** [March 25, 2011, 12:42am UTC](https://www.ruby-forum.com/t/ruby-ffi-port/204843/6 "2011-03-25T00:42:25Z")

</div>

I’ve fixed the problem in the spec [https://github.com/ffi/ffi/pull/82](https://github.com/ffi/ffi/pull/82),  
and  
all specs pass now. Time to start porting the C code to C#.

-Charles

On Thu, Mar 24, 2011 at 3:19 PM, Charles S. \<

---

<div class="post-metadata">

**Author:** ![valdar](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/b5a626/32.png) [@valdar](https://www.ruby-forum.com/u/valdar)\
**Post date:** [March 25, 2011, 1:24am UTC](https://www.ruby-forum.com/t/ruby-ffi-port/204843/7 "2011-03-25T01:24:43Z")

</div>

On 25 March 2011 04:58, Charles S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> > Another idea what about starting fromhttp://github.com/ffiand replacing  
> > the C extension with C# code?
> 
> That’s a great idea, Tomas. I’ll need some immediate gratification to keep  
> me from getting discouraged; porting the C funcspiecemeal sounds like a  
> good way to get something working. I’veforked FFI - I’ll try to lay out a  
> foundation tonight.

If you want some easy wins, The first classes you’ll want to implement  
are:

1. FFI::Type - this is used by much of the rest of the system, e.g.  
to identify arguments and struct field types. At a minimum, you need  
to implement #size and #alignment, and have FFI::Type instances for 8,  
16, 32, 64 bit signed/unsigned integers, float, double and pointer  
defined as the constants FFI::Type::UINT8, FFI::Type::INT8, etc.

2. FFI::Pointer - instances of this are used to represent a native  
pointer. To get things up and running, you can stub this out with  
just the basic initialize() method. Most of the accessor methods can  
be done later.

3. FFI::DynamicLibrary - kinda useful for loading libraries and  
locating symbols within said library.

4. FFI::Function - the swiss army knife class for calling functions,  
and creating C =\> ruby callbacks. Ignore the callback aspect of this  
for now, and just get ruby =\> C calling working.

That will take you a little while, but you’ll be able to at least get  
simple functions like ‘puts’ from libc callable from FFI.

---

<div class="post-metadata">

**Author:** ![valdar](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/b5a626/32.png) [@valdar](https://www.ruby-forum.com/u/valdar)\
**Post date:** [March 25, 2011, 11:40am UTC](https://www.ruby-forum.com/t/ruby-ffi-port/204843/8 "2011-03-25T11:40:58Z")

</div>

Sweet - thank you for the tip, Wayne!

Here’s my current plan:

- All Ruby classes defined inside of ffi\_c will be ported to Ruby,  
where  
I’ll call into my C# lib where it makes sense.
- Because my poor brain can only handle so much context-switching,  
I’ll  
stub out all of the Ruby classes with methods that will simply _raise  
“not implemented”_.
- I’ll follow Wayne’s advice to get some simple clib funcs working.
- Port the rest of ffi\_c

When all is said and done, it looks like I shouldn’t need to touch a  
single  
line of FFI’s Ruby code - I _should_ only need to implement classes (or  
parts thereof) that are defined in ffi\_c.

One thing I will need to figure later is the name of the dll that  
contains  
dlopen/dlsym/etc for each platform. I’m willing to be that I’ll be able  
to  
piece that together with decent accuracy by looking at  
FFI.map\_library\_name.

-Charles

---

<div class="post-metadata">

**Author:** ![valdar](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/b5a626/32.png) [@valdar](https://www.ruby-forum.com/u/valdar)\
**Post date:** [March 25, 2011, 2:50pm UTC](https://www.ruby-forum.com/t/ruby-ffi-port/204843/9 "2011-03-25T14:50:47Z")

</div>

That sounds like a good plan. Much of the CRuby version of FFI used  
to be written in ruby, until people had the quaint notion that it  
shouldn’t be as slow as it was, and I moved most of the implementation  
into C.

dlopen and friends are usually in the libdl library on most unixen. I  
can’t remember where the windows equivalents live.
