Ruby コードに変換する必要がある C コードがあります。参照用の C コードを次に示します。
//bundle_ingest.h
typedef void
(* bundle_read_fn)(
gsdk_void_t* callback_data,
gsdk_byte_t* buffer,
gsdk_size_t buffer_size,
gsdk_size_t* p_bytes_read,
gsdk_bool_t* abort
);
gsdk_error_t bundle_ingest(
gsdk_void_t* callback_data,
bundle_read_fn bundle_read_fn
);
//main.c
void bundle_read_callback(
gsdk_void_t* callback_data,
gsdk_byte_t* buffer,
gsdk_size_t buffer_size,
gsdk_size_t* p_bytes_read,
gsdk_bool_t* abort
)
{
if((callback_data == NULL) || (buffer == NULL) || (p_bytes_read == NULL))
{
*abort = TRUE;
return;
}
*p_bytes_read = fread(buffer, 1, buffer_size, (FILE *)callback_data);
}
int main()
{
FILE *fp = NULL;
gsdk_error_t error = GSDK_SUCCESS;
fp = fopen("mybundle.b", "rb");
//1. this call invokes the bundle_read_callback function
//2. definition of bundle_ingest() is in bundle_ingest.dll which I am linking
//
error = bundle_ingest((void *)fp, bundle_read_callback);
//if error = 0, I get the desired file generated in my current working folder.
return 0;
}
MY QUESTION: 同じコードを Ruby で実装したいと考えています。コールバック関数の「fread」呼び出しを除いて、すべてのコードを Ruby で記述しました。Ruby での C の fread() 関数への代替呼び出しの方向または解決策を誰かに教えてもらえますか。参考までに、「ffi-libc」はすでに試しましたが、うまくいきません。
注: Ruby で C 関数を呼び出すために FFI を使用しています。参考までにRubyコードを載せておきます。
module Bundle
FFI.add_typedef(:pointer, :GsdkCallbacksS)
callback :bundle_read_fn, [ :pointer, :pointer, :gsdk_size_t, :pointer, :pointer ], :void
class GsdkCallbacksS < FFI::Struct
layout(
:callback_fpbundle_read, :bundle_read_fn
)
end
attach_function :bundle_ingest, [ :pointer, :bundle_read_fn ], :gsdk_error_t
end
class Ingestion
include Bundle
BundleReadCallback = Proc.new do | callback_data, buffer, buffer_size, p_bytes_read, abort|
puts "\ninside BundleReadCallback\n\n"
if((callback_data == nil) or (buffer == nil) || (p_bytes_read == nil))
abort.wtire_pointer(true)
return
end
##################################################################################
## TODO: Ruby alternate to C's fread() ##
## C call: *p_bytes_read = fread(buffer, 1, buffer_size, (FILE *)callback_data);##
##################################################################################
end
def ingest_bundle (bundlle_file)
callback = GsdkCallbacksS.new
callback[:callback_fpbundle_read] = BundleReadCallback
size = File.size(bundle_file)
open(bundle_file, "rb") do |io|
fp = io.read(size)
error = bundle_ingest(fp, callback[:callback_fpbundle_read])
puts "bundle_ingest, error = #{error}"
io.close
end
end
end
### Ruby main.rb
bi = Ingestion.new
bi.ingest_bundle("mybundle.b")