Unpacking fiddle pointer after C

#1

I’m trying to use Fiddle to communicate with a C++ DLL in windows. I seem to get the information into C just fine, but reading the values back at ruby is giving me a bit of a headache.

My C++ -function is like this:

struct datatransfer {
	int numberofvalues;
	double* values;
};

extern "C" __declspec(dllexport) datatransfer* doublevalues(datatransfer* todouble)
{
	for (int counter = 0; counter < todouble->numberofvalues; counter++)
	{
		todouble->values[counter] *= 2;
	}
	return(values);
}

And on ruby’s side I’m doing this:

require 'fiddle'
require 'fiddle/import'

module Fiddletestmodule
  extend Fiddle::Importer

  Datatransfer=struct [
  'int numberofvalues',
  'double* thevalues'
  ]

 dlload 'visualstudiodll/fiddletestdll'
  extern 'Datatransfer* doublevalues(Datatransfer*)'

end

inputvalues = [1.0, 2.0, 3.0]
ptr=Fiddle::Pointer[inputvalues.pack('D*')]
totransfer=Fiddletestmodule::Datatransfer.malloc
totransfer.numberofvalues=3
totransfer.thevalues=ptr
valuesafterc=Fiddletestmodule.doublevalues(totransfer)

Now it looks like I can get the values inside of C just fine, and the function there works as expected. Getting a single double back works fine as well. But how should I read that packed value afterwards, that is, how do I open the “thevalues” array of either “valuesafterc” or “totransfer” after the c-function? All of my tests for that seem to fail.

The outcome is a structure that has the “thevalues” in their packed format. But if I try to do something like totransfer.thevalues.unpack('D*') or totransfer.thevalues.to_value, I usually end up crashing the interpreter. (Unpacking “valuesafterc” is exactly the same).

Would anyone know the correct way to read the results?

#2

I still haven’t been able to make that work in fiddle. But this seems to work differently (and better, for my purposes) in pure FFI. This thing works, actually getting the modified values back:

require 'ffi'

class Datatransfer < FFI::Struct
  layout :numberofvalues, :int,
  :thevalues, :pointer
end

module Ffitest
  extend FFI::Library

  ffi_lib '../visualstudiodl/fiddletestdll'

  attach_function :doublevalues, [Datatransfer], Datatransfer
end

inputvalues= [1.0, 2.0, 3.0]
size=inputvalues.size

pointer=Datatransfer.new FFI::MemoryPointer.new :char, Datatransfer.size
pointer[:numberofvalues]=3
pointer[:thevalues]=FFI::MemoryPointer.new :double,size
pointer[:thevalues].put_array_of_double(0,inputvalues)
resultnotneededinthiscase=Ffitest.doublevalues(pointer)

#Now this will output values that have actually been doubled:
p pointer[:thevalues].get_array_of_double(0,size)