2011-01-07 2 views
2

나는 MIDI 입력 장치 (키보드)에서 정보를 인쇄하기 위해 몇 가지 기본적인 Windows 호출을 시도하려고합니다. 전화가 작동하는 것처럼 보이지만 midiInOpen 및 midiInStart에 대한 처음 두 번의 호출은 MMSYSERR_NOMEMMMSYSERR_INVALHANDLE을 반환합니다. 나는 그것이 ptr = FFI::MemoryPointer.new(:pointer)과 관련이 있다고 믿지만, FFI에 대해 충분히 알지 못한다. 어떤 도움을 주셔서 감사합니다.도움말 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 이후에 excactly 한 번 호출됩니다. 그런 다음 midiInStart를 호출하면 결과는 MMSYSERR_INVALHANDLE입니다. 문제가 무엇인지 또는 midiInOpen에서 설정할 올바른 플래그가 무엇인지 알아 냈는 지, 오류가 사라 졌는가? – Michael

답변

1

명확한 대답 문제입니다) 코드는 대부분 정확 보이지만, 나는 그것이 dwFlags (마지막 PARAM)는 midiInOpen (에 전달하는 의심한다. http://msdn.microsoft.com/en-us/library/dd798458(v=vs.85).aspx을 보면 0이 아니어야합니다.

winmm 헤더 파일에서 CALLBACK_FUNCTION의 값을 찾고 비슷한 상수를 모듈에 선언 한 다음 플래그 매개 변수로 사용하십시오.

http://powersdr-iq.googlecode.com/svn/trunk/Source/Console/midi.cs에는 C# P/Invoke 인터페이스를 사용하여 다른 API를 래핑하는 유용한 예가 될 수있는 C# 래퍼가 있습니다.

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에 의해 답변 됨으로 인해 발견했다고 생각합니다.

감사합니다.