Thanks Brian for the detailed explanation. I wonder if your Pointer extension shouldn't be merged into HotCocoa or MacRuby itself.
What do you guys think? - Matt On Wed, Feb 25, 2009 at 12:43 PM, Brian Chapados <cha...@gmail.com> wrote: >> Can you explain: "^{_CGLRendererInfoObject=}"? is that some secret >> incantation only known by the MacRuby/Obj overlords? > > Yes, it is actually a 7th level spell: 'Encode Structure'. To learn > it, you must study the ancient tome: > http://developer.apple.com/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/chapter_7_section_1.html#//apple_ref/doc/uid/TP40008048-CH100-SW1 > > If it makes you feel better, I usually need to look it up (or just > run the Obj-C code sample), unless it is something simple (like '@'). > I don't keep this spell in memory, as it is only required in special > situations. > > Seriously though, that is actually how you encode a pointer to a > struct. If you use the @encode(type) directive, the compiler will > return the runtime encoding for 'type'. It's a bit cryptic, but not > too bad once you know the syntax: > > '^type' encodes a pointer to type. > '{name=<field1 type><field2 type><field3 type>...<fieldN type>}' > encodes a struct with N fields. > > To break it down using 2 examples: > > (from the docs) > typedef struct example { > id anObject; // encoding = @ > char *aString; // encoding = c > int anInt; // enoding = i > } Example; > > @encode(Example) = "^{examp...@ci}" > > CGLRendererInfoObj is a pointer to an opaque struct (we don't know > anything about the fields) named _CGLRendererInfoObject. All we know > is: > typedef struct _CGLRendererInfoObject *CGLRendererInfoObj; > > so it's just "^{_CGLRendererInfoObject=}" > > In practice (unless you're working with CoreFoundation C APIs) you > usually just need a pointer to an object. The most common usage I run > across is to retrieve NSError objects. The CoreFoundation C API uses > pass-by-reference extensively. To use these functions with MacRuby, > you need to create lots of pointer objects. In general, this is an > area where interfacing ruby with C is just fugly. I'd personally > avoid doing this in MacRuby. If you find yourself needing to use lots > Pointer objects, it's probably better and less error-prone to write > that code in C and expose it to MacRuby through an Objective-C > interface. > > That said, for common things, I've used something like this extension > to the Pointer class: > > ---- > class Pointer > def self.ptr > new_with_type("@") > end > > def self.to(type = :object) > case type > when :object > new_with_type('@') > when :int > new_with_type('i') > when :char > when :bool > when :BOOL > new_with_type('c') > when :unsigned > new_with_type('I') > end > end > > def value > self[0] > end > end > > ---- > > Need a pointer to an ObjC object? > p = Pointer.ptr > > To a BOOL? > p = Pointer.to(:BOOL) > > Need the value? > p.value > > Those are the most common types I've needed. > > On Wed, Feb 25, 2009 at 11:11 AM, Matt Aimonetti > <mattaimone...@gmail.com> wrote: >> Brian, what's up with this syntax: info = >> Pointer.new_with_type("^{_CGLRendererInfoObject=}") >> Can you explain: "^{_CGLRendererInfoObject=}"? is that some secret >> incantation only known by the MacRuby/Obj overlords? >> Thanks, >> - Matt >> >> On Wed, Feb 25, 2009 at 10:13 AM, Brian Chapados <cha...@gmail.com> wrote: >>> >>> CGLRendererInfo is a pointer to a struct: >>> typedef struct _CGLRendererInfoObject *CGLRendererInfoObj; >>> >>> try creating a pointer to void or to the struct: >>> >>> info = Pointer.new_with_type("^v") # void *info; >>> >>> or >>> >>> info = Pointer.new_with_type("^{_CGLRendererInfoObject=}") # >>> CGLRendererInfo *info >>> >>> I think the second one is effectively the same as what you were trying >>> to do with: >>> info = Pointer.new_with_type("CGLRendererInfoObj") >>> >>> except that the runtime doesn't know what to do with >>> "CGLRendererInfo". The argument to Pointer.new_with_type must be a >>> valid Objective-C type encoding[1]. >>> >>> [1]: >>> http://developer.apple.com/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/chapter_7_section_1.html#//apple_ref/doc/uid/TP40008048-CH100-SW1 >>> >>> If you are ever in doubt about what encoding to use, you can always >>> compile a small Objective-C program that prints out the output of >>> @encode(). For example: >>> >>> #import <Foundation/Foundation.h> >>> #import <OpenGL/OpenGL.h> >>> >>> int main(int argc, char *argv[]) >>> { >>> char *encoding = @encode(CGLRendererInfoObj); >>> printf("\nencoding => %s\n\n", encoding); >>> return 0; >>> } >>> >>> compile with: >>> gcc -Wall -o encode encode.m -framework Foundation -framework OpenGL >>> >>> then run: >>> ./encode >>> >>> Maybe there is an easier way to obtain the output of @encode(). I'm not >>> sure. >>> >>> Brian >>> >>> On Wed, Feb 25, 2009 at 1:42 AM, Julien Jassaud <jul...@collectapply.jp> >>> wrote: >>> > Hello, >>> > I am trying to port the Cocoa OpenGL sample to MacRuby and encountered a >>> > few >>> > problems. >>> > >>> > First, I can't access some constants defined in an enum in GLTypes.h. Do >>> > I >>> > need to port those constants to ruby by hand ? Is that related >>> > to gen_bridge_metadata ? >>> > >>> > Second, I need to use CGLQueryRendererInfo >>> > and CGLDescribeRenderer functions. The first one requires a pointer to >>> > a CGLRendererInfoObj structure but the second requires the object to be >>> > passed directly. I tried some C style pointer arithmetic : >>> > info = Pointer.new_with_type("CGLRendererInfoObj") >>> > count = Pointer.new_with_type("l") >>> > CGLQueryRendererInfo(caps[:cgl_display_mask], info, count) <- works >>> > fine, >>> > but CGLRendererInfoObj is opaque so I can't check it in irb. >>> > CGLDescribeRenderer(info[0], 0, kCGLRPRendererCount, count) <- I naively >>> > tried to dereference the pointer, but it doesn't work. >>> > CGLDescribeRenderer(info, 0, kCGLRPRendererCount, count) <- No >>> > complaints, >>> > but the value for count[0] is not consistent (100468704 renderers). >>> > I see in MacIRB that there is a CGLRendererInfoObj class but I >>> > can't instantiate it. >>> > This is all new to me and I may be overlooking something obvious. If >>> > anyone >>> > has an idea, please help. >>> > Thanks, >>> > Julien Jassaud >>> > _______________________________________________ >>> > MacRuby-devel mailing list >>> > MacRuby-devel@lists.macosforge.org >>> > http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel >>> > >>> > >>> _______________________________________________ >>> MacRuby-devel mailing list >>> MacRuby-devel@lists.macosforge.org >>> http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel >> >> >> _______________________________________________ >> MacRuby-devel mailing list >> MacRuby-devel@lists.macosforge.org >> http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel >> >> > _______________________________________________ > MacRuby-devel mailing list > MacRuby-devel@lists.macosforge.org > http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel > _______________________________________________ MacRuby-devel mailing list MacRuby-devel@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel