The Crystal Programming Language Forum

C bindings for functions with arrays of arrays parmeters

Hi,
I am trying to write bindings for a C library where all functions are defined by pair in the same manner, as in the following :

int xxx_start(double const *options);
int xxx(int size,
        double const *const *inputs,
        double const *options,
        double *const *outputs);

xxx_start must be called first to compute outputs subarrays size.
The first 3 parameters of xxx are input data, and the 4th collects the results of the function.

So, In Crystal, the types are :

inputs : Array(Array(Float64))
options : Array(Float64)
outputs : Array(Array(Float64))

I got it to work with :

lib LibXXX
  fun xxx_start(Float64*) : Int32
  fun xxx(Int32, Float64**, Float64*, Float64**) : Int32
end

Example :

data_in = [5.0, 8.0, 12.0, 11.0, 9.0, 8.0, 7.0, 10.0, 11.0, 13.0]
options = [3.0]
start = LibXXX.xxx_start(options)
output_size = data_in.size - start
data_out = Array.new(output_size, 0.0)
error = LibXXX.xxx(data_in.size, [data_in.to_unsafe].to_unsafe, options, [data_out.to_unsafe].to_unsafe)

This works fine, but I’d like to avoid the use of the unsafe method inside ‘user’ code.
How can I do that ?

Thanks for help.

[EDIT]
Got it to work with the following wrapper method :

def wrapper(function : Symbol, isize : Int32, inputs, options, outputs) : Int32
  case function
  when :xxx
    LibXXX.xxx(isize,
      inputs.map { |a| a.to_unsafe }.to_unsafe,
      options.to_unsafe,
      outputs.map { |a| a.to_unsafe }.to_unsafe)
  else
    1
  end
end
error = wrapper(data_in.size, [data_in], options, [data_out])

Is there a better alternative ?

StaticArray(T, N) where T is a type of array and N is size of static array is what you have to use. In that case they are already in the proper format, same as C arrays.

If array is dynamic then Array.to_unsafe should do the trick as it will return pointer to Array(T).buffer address.