1

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")
4

1 に答える 1