Subject:
[ruby-ffi] Re: Reading struct elements returning incorrect values
From:
Wayne Meissner
Date:
6/16/12 1:27 AM
To:
ruby-ffi@googlegroups.com

Shouldn't this line:

 item = VarnamLibrary::Token.new(ptr)

be:

 item = VarnamLibrary::Token.new(tok)

i.e. cast the return value from varray_get() to a Token struct?

As it stands, your code is casting the varray itself to a Token.

On Friday, 15 June 2012 12:42:27 UTC+10, Navaneeth KN wrote:
Hello,

I have a C function like,

   int varray_length (varray*)
   void* varray_get(int index)

FFI mappings like,

  attach_function :varray_get, [:pointer, :int], :pointer
  attach_function :varray_length, [:pointer], :int

My C structure looks like,

typedef struct token {
    int type, match_type;
    char tag[TOKEN_TAG_MAX];
    char pattern[SYMBOL_MAX];
    char value1[SYMBOL_MAX];
    char value2[SYMBOL_MAX];
    int children;
} vtoken;

FFI struct like,

  class Token < FFI::Struct
    layout :type, :int,
    :match_type, :int,
    :tag, [:char, TOKEN_TAG_MAX],
    :pattern, [:char, SYMBOL_MAX],
    :value1, [:char, SYMBOL_MAX],
    :value2, [:char, SYMBOL_MAX],
    :children, :int,
  end

I am invoking a C function which has signature like,

  int get_all_tokens(varnam*, int, varray **output)

Invoiking this using FFI like,

  token_ptr = FFI::MemoryPointer.new :pointer
  done = VarnamLibrary.varnam_get_all_tokens($varnam_handle.get_pointer(0), token_type, token_ptr);

This call succedes and I get a varray instance assigned to token_ptr. All is good. Now when I try to read data from this pointer, I am getting empty values. I am doing it like,

  size = VarnamLibrary.varray_length(token_ptr.get_pointer(0)) --- This works
  i = 0
  until i >= size
    tok = VarnamLibrary.varray_get(token_ptr.get_pointer(0), i)   - This succeds
    ptr = token_ptr.read_pointer
    item = VarnamLibrary::Token.new(ptr)      - This works, but all properties of item will be empty.
    varnam_token = VarnamToken.new(item[:type],
                                   ffito_string(item[:pattern]), ffito_string(item[:value1]),
                                   ffito_string(item[:value2]), item[:match_type])       - This gives me a token with empty values for strings and some random values for integers
    i += 1
  end

I am wondering why this happens. Any help would be great.

Thanks
Navaneeth