[MacRuby-devel] How to use custom C struct's?

Laurent Sansonetti lsansonetti at apple.com
Wed Aug 5 13:09:36 PDT 2009


On Aug 5, 2009, at 12:57 PM, Laurent Sansonetti wrote:
> On Aug 5, 2009, at 8:41 AM, Eloy Duran wrote:
>
>> Hi,
>>
>> On Aug 5, 2009, at 5:31 PM, Clay Bridges wrote:
>>> The google didn't yield much guidance on this. Before I started a
>>> deep-dive on the MacRuby source, and/or the standard ruby way to
>>> handle this sort of thing, I thought I would ask a couple of
>>> questions:
>>>
>>> 1) Any easy advice?
>>
>> Yes, use RubyCocoa
>>
>>> 2) Is this different in MacRuby than in ruby proper?
>>
>> RubyCocoa at least allows you to use BridgeSupport which would  
>> allow you to map these. Afaik MacRuby doesn't fully support it yet.
>>
>>> 3) Any pointers into the MacRuby source that might help me?
>>
>> BridgeSupport needs to fully implemented.
>
> FYI, BridgeSupport is mostly implemented in MacRuby, at least the  
> part that deals with C structures. The only part that we didn't  
> implement yet is C function pointers, the rest (roughly 90%) is  
> done, and it is faster / more stable than the RubyCocoa code (you  
> will have to believe me, since I wrote both :-)).
>
> What Clay needs to do is describe his C structures in  
> a .bridgesupport file.
>
> You can read the BridgeSupport(5) man-page for more information.  
> Unfortunately the gen_bridge_metadata(1) cannot generate C  
> structures metadata without a template, and this part is not yet  
> documented. So it may be faster to craft the .bridgesupport file by  
> hand. There are plenty of .bridgesupport files in /System/Library/ 
> Frameworks that can be used as an example.
>
> Once the file is created, it can loaded from MacRuby using:
>
>  load_bridge_support_file 'foo.bridgesupport'

Here is an example on how to do this automatically.

First, I created a header file with your code.

$ cat t.h
struct MapPoint {
  int row;
  int col;
};
typedef struct MapPoint MapPoint;

Now, I generate an exceptions template file based on your header file.

$ gen_bridge_metadata -F exceptions-template -c '-I.' t.h >  
exception.xml

The exceptions template file contains the name of your struct. The  
generator uses an exception because we don't want to expose all C  
structures by default, so it gives the developer a choice. Here we  
leave it empty, which means MapPoint will be exposed.

$ cat exception.xml
<?xml version='1.0'?>
<!DOCTYPE signatures SYSTEM "file://localhost/System/Library/DTDs/BridgeSupport.dtd 
">
<signatures version='0.9'>
<struct name='MapPoint'/>
</signatures>

Now, we generate the real .bridgesupport file, passing the exceptions  
file.

$ gen_bridge_metadata -e ./exception.xml -c '-I.' t.h >  
mappoint.bridgesupport

As you can see, it contains a signature for MapPoint.

$ cat mappoint.bridgesupport
<?xml version='1.0'?>
<!DOCTYPE signatures SYSTEM "file://localhost/System/Library/DTDs/BridgeSupport.dtd 
">
<signatures version='0.9'>
<struct name='MapPoint'  
type='{MapPoint=&quot;row&quot;i&quot;col&quot;i}'/>
</signatures>

And now, you can load it from MacRuby and use it as if it was a real  
Ruby class. Actually it's a real Ruby class :-)

$ macruby -e "load_bridge_support_file('mappoint.bridgesupport'); p  
MapPoint.new(1, 2)"
#<MapPoint row=1 col=2>

HTH,
Laurent


More information about the MacRuby-devel mailing list