[MacRuby-devel] Interfacing with C (not objective C)

Brian Chapados chapbr at gmail.com
Tue Mar 17 21:25:40 PDT 2009


I think that if you need to make use extensive use of C
functions/libraries, then the least painful route is to wrap this
functionality in Objective-C classes.  Writing Objective-C classes
that call your C code is easier than writing C ruby extensions.  At
least in my opinion, this is why MacRuby makes it easier to interface
with C. Just create a dylib or framework, load it in MacRuby and use
it.

Note that there is currently no way to bridge arbitrary C functions
anyway, so if you want something that isn't covered by BridgeSupport,
your only option right now is to wrap it in Objective-C.

For pointers, MacRuby currently provides a simple Pointer class that
allows you to:
1. pass around a pointer
2. access the value (dereference)
3. assign the value that is pointed to (this allocates memory that is
pointed to)

There really isn't a way to get a pointer to a MacRuby function and
pass that to a C function.  So callback-type situations would have to
be wrapped in Objective-C.

You can do:

1. a. Memory handed to the asynchronous routine can't move i.e. no
garbage collection

if you create a Pointer and assign a value to it, then memory gets
allocated and should be safe as long as the Pointer object stays
around. For example:

p = Pointer.new_with_type("i")
p.assign(5)
my_c_function(p)

3. b. If the caller is allocating the memory, you can create a Pointer
object, pass it to the caller and then access the value.  This
requires that you know the type. An example of this is dealing with
pointers to NSError objects.  For example:

errorp = Pointer.new_with_type("@")

result = my_data.writeToURL(save_url, options:nil error:errorp)

# access error
errorp[0]

3. c  You would need to be able to assign the type to a Pointer that
you do not create (not currently possible).  After looking at objc.m,
I think this could be added. However, it would be somewhat dangerous.
If you really need to read packed bit fields and things you can't do
with Array#pack / unpack, then I would probably wrap that code.

Brian

On Mon, Mar 16, 2009 at 8:37 PM, Martin Hess <martinhess at mac.com> wrote:
> My apologies if this has been covered somewhere else, but how do you
> interface with C in MacRuby. I know you can just write a C extension for
> Ruby but it appears that MacRuby makes this easier but it is unclear to me
> how far its support goes and when you should write an extension.
>
> Someone was asking about OpenGL in another thread which is a great example
> of a more difficult case but I don't think it covers all cases in a general
> sense. I'll break up the problem as I see it:
>
> 1) External C routines can be asynchronous
>        a) Memory handed to the asynchronous routine can't move i.e. no
> garbage collection
>        b) Call backs (i.e. passing in function pointers to a C routine)
>                i.  Asynchronous routines can show up at anytime
>
> 2) Function pointers as parameters to external C routines
>        a) Function signature has to match exactly i.e. can't pass in a Ruby
> method pointer
>
> 3) Memory
>        a) Allocated by external C routine
>                i) How to delete if it is the callers responsibility to
> delete
>        b) Allocated by caller
>                i) How to allocate and get valid pointer to memory that isn't
> going to get garbage collected away
>        c) Reading and writing allocated memory
>                i) This is raw memory with no type information
>                ii) How do you give it shape so you can read and write
> symbolically i.e. no peek/poke
>                iii) Reading and writing packed bitfields
>
>
> So how are each of these things done in
> MacRuby?_______________________________________________
> MacRuby-devel mailing list
> MacRuby-devel at lists.macosforge.org
> http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
>


More information about the MacRuby-devel mailing list