我有一个 C 代码,我需要将其转换为 Ruby 代码。这是供您参考的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;
}
我的问题:我想在 Ruby 中实现相同的代码。除了回调函数中的“fread”调用之外,我已经用 Ruby 编写了所有代码。谁能为我提供在 Ruby 中交替调用 C 的 fread() 函数的方向或解决方案。仅供参考,我已经尝试过'ffi-libc',但这对我不起作用。
注意:我使用 FFI 在我的 Ruby 中调用 C 函数。这是供您参考的 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")