creating a Dynamic array class in ruby using FFI and C function

It seems that you are not working with the C code properly.

In create_array C function:

  • you are not returning the array, so there's no way the ruby code will work with the newly created array, you need to return it
  • if you want to return an array you actually need to return it's pointer
  • In C, in order to create an array and the size is not known before compilation you need to allocate it's memory with malloc (or some other function in the allocfamily)

to put it all together, this is how your create_array.c file would look like:

#include <stdlib.h> /* in order to use malloc */

int * create_array (int size){
  int *a = malloc(size * sizeof(int));
  return a; /* returning the pointer to the array a*/
}

and your header file create_array.h:

int * create_array(int);

and to wrap everything up you still need to compile it before ruby can touch it:

gcc -shared -o create_array.so -fPIC create_array.c

this command is using gcc to compile your C code into a shared library called create_array.so from create_array.c source file. gcc needs to be installed for this to work.

Finally you can use the C function in ruby, with some modifications in your dynamic_array.rb:

require 'ffi'
class DynamicArray
  extend FFI::Library
  ffi_lib "./create_array.so" # using the shared lib
  attach_function :create_array, [:int], :pointer # receiving a pointer to the array
  # rest of your code

Now, this should work! But there are still some issues with your ruby code:

  • when you do @static_array = create_array(@capacity) you are receiving a C pointer to the allocated array, not the array itself, not at least in ruby.
  • writing @static_array[@current_index] = element will not work NoMethodError: undefined method '[]=' for #<FFI::Pointer address=0x000055d50e798600>
  • If you want to add an element to the array, C code must do it. Something like:
void add_to_array (int * array, int index, int number){
  array[index] = number;
}
attach_function :add_to_array, [:pointer, :int, :int], :void
add_to_array(@static_array, @current_index, element)
  • Same goes for the @static_array.each_with_index you need to code this in C.

Tags:

C

Ruby

Ffi