Subject: Re: [ruby-ffi] Help with array of strings in a struct |
From: Chuck Remes |
Date: 5/13/10 10:27 PM |
To: ruby-ffi@googlegroups.com |
On May 13, 2010, at 8:14 AM, Drew wrote:
Hello, I'm trying to create an FFI wrapper for an Adobe Framemaker automation library. Here's the sample code in C that I'm trying to re- create in Ruby: IntT j = 0; UIntT i; F_IntsT attributes; F_StringsT strings; /* Get name of each FontFamily and display it based on whether it is visible * in PGF Designer. */ strings = F_ApiGetStrings(0, FV_SessionId, FP_FontFamilyNames); attributes = F_ApiGetInts(0, FV_SessionId, FP_FontFamilyAttributes); for(i=0; i<attributes.len; i++){ j = attributes.val[i]; if(j & FV_FAMILY_VISIBLE) F_Printf(NULL,"Family %s\n", strings.val[i]); } F_StringsT looks like this: typedef struct { UIntT len; StringT *val; } F_StringsT; StringT is defined as unsigned char *, so I think I'm trying to read an array of pointers to strings, or unsigned char **. Right now I'm just trying to get the strings in Ruby: # in my FFI module FM: class FStringsT < FFI::Struct layout :len, :int, :val, :pointer end attach_function :FApiGetStrings,[:int,:int,:int], FStringsT.by_value # in my script: strings = FM.FApiGetStrings(0, FM.FVSessionId, FM.FPFontFamilyNames) attributes = FM.FApiGetInts(0, FM.FVSessionId, FM.FPFontFamilyAttributes) puts strings[:len], attributes[:len] # => 337 strptr = strings[:val].read_pointer() if !( strptr.null? ) puts strptr # => #<FFI::Pointer:0x3bd0e04> sa = strptr.get_array_of_string(0,strings[:len]).compact # => causes seg fault puts sa end
Wow, lots of information here. Let's try to break it down a bit. Let's eliminate the #compact call. Without it, can you successfully read and access those members? Do you know that the read to strings[:len], attributes[:len] should output 337? Is that right or a guess? You have a lot going on here. Please simplify it or the diagnosis may be wrong. cr