2011-01-07 25 views
2

私は単に、MIDI入力デバイス(キーボード)から情報を印刷するために、いくつかの基本的なWindows呼び出しを試みています。コールは機能しているようですが、midiInOpenとmidiInStartの最初の2回のコールはMMSYSERR_NOMEMMMSYSERR_INVALHANDLEです。私はそれがptr = FFI::MemoryPointer.new(:pointer)と関係があると信じていますが、私はそれを理解するためにFFIについて十分に知りません。どんな助けもありがとうございます。Help with Ruby FFI

require 'ffi' 

module MIDI; end 

module MIDI::Input 
    extend FFI::Library 

    ffi_lib 'winmm' 
    ffi_convention :stdcall 

    callback :midiInProc, [ :pointer, :uint, :int, :int, :int ], :void 

    attach_function :midiInOpen, [ :pointer, :uint, :midiInProc, :int, :int ], :int 
    attach_function :midiInClose, [ :long ], :int 

    attach_function :midiInStart, [ :long ], :int 
    attach_function :midiInStop, [ :long ], :int 
    attach_function :midiInReset, [ :long ], :int 

    MidiInProcCallback = Proc.new do |hmidiin, wmsg, dwintance, dwparam1, dwparam2| 
    p hmidiin, wmsg, dwintance, dwparam1, dwparam2 
    end 
end 

require 'pp' 
ptr = FFI::MemoryPointer.new(:pointer) 
p MIDI::Input.midiInOpen(ptr, 0, MIDI::Input::MidiInProcCallback, 0, 0) 
p MIDI::Input.midiInStart(ptr.read_long) 

trap("INT") do 
    p MIDI::Input.midiInStart(ptr.read_long) 
    p MIDI::Input.midiInClose(ptr.read_long) 
    p ptr.free 
    exit 
end 

loop {} 
+0

Ryanへの質問:私はここでも同じ問題があります。 midiInOpenの結果はMMSYSERR_NOERRORであり、コールバック関数はmidiInOpenの後に1回excactly呼ばれます。次にmidiInStartを呼び出し、結果はMMSYSERR_INVALHANDLEです。問題が何であるか、midiInOpenで設定する正しいフラグは何か、エラーが解消したことを確認しましたか? – Michael

答えて

1

明確な答えは、あなたのコードとして主に正しい見えませんが、私はそれはあなたが問題であるmidiInOpen()に渡していdwFlagsパラメータ(最後のparam)である疑いがあります。 http://msdn.microsoft.com/en-us/library/dd798458(v=vs.85).aspxを見ると、ゼロでない必要があるようです。

WinmmヘッダーファイルでCALLBACK_FUNCTIONの値を調べ、モジュールで同様の定数を宣言してから、フラグparamとして使用してください。

http://powersdr-iq.googlecode.com/svn/trunk/Source/Console/midi.csにC#ラッパーがあります。このラッパーは、C#P/Invokeインターフェイスを使用して同じAPIをラップする他のユーザーにとって便利な例です。

midiInOpenのシグネチャとコールバックが多少間違っています(ただし、この問題は発生しません)。彼らは、次のようになります。

callback :midiInProc, [ :pointer, :uint, :pointer, :pointer, :pointer ], :void 

attach_function :midiInOpen, [ :pointer, :uint, :midiInProc, :pointer, :int ], :int 

すなわち使用:APIドキュメントがDWORD_PTR

+0

これは 'MMSYSERR_NOMEM'と' MMSYSERR_INVALHANDLE'エラーを止めたようです。コールバック関数は動作していないようです。 – RyanScottLewis

+0

http://en.wikipedia.org/wiki/Message_loop_in_Microsoft_Windowsに示すように、Windowsメッセージループをポンピングする必要がありますか? –

0

を使用するポインタがhttps://github.com/arirusso/midi-winmm/blob/master/lib/midi-winmm/map.rb

ああを見てください!それはあなたの一部です。クール。できます。

私はそれを試したので、私はWindowsでこの作品を知っています。私の最大の望みはwinmm.dll apiのMicrosoftからのドキュメントを見つけることです。私はあなたの質問がuser186057によって答えられていることに感謝しています。

ありがとうございました。