Помощь с Ruby FFI - PullRequest
       6

Помощь с Ruby FFI

2 голосов
/ 07 января 2011

Я просто пытаюсь сделать несколько основных вызовов Windows, чтобы напечатать информацию с устройства ввода MIDI (клавиатура).Кажется, что вызовы работают, но первые два вызова midiInOpen и midiInStart возвращают MMSYSERR_NOMEM и MMSYSERR_INVALHANDLE.Я считаю, что это как-то связано с ptr = FFI::MemoryPointer.new(:pointer), но я не знаю достаточно о 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 {}

Ответы [ 2 ]

1 голос
/ 07 января 2011

Нет точного ответа, так как ваш код выглядит в основном правильно, но я подозреваю, что именно dwFlags (последний параметр), который вы передаете midiInOpen (), является проблемой.Глядя на http://msdn.microsoft.com/en-us/library/dd798458(v=vs.85).aspx,, кажется, что он должен быть ненулевым.

Попробуйте поискать в заголовочном файле winmm значение CALLBACK_FUNCTION и объявите аналогичную константу в своем модуле, затем используйте еев качестве параметра флагов.

Существует обертка C # в http://powersdr -iq.googlecode.com / svn / trunk / Source / Console / midi.cs , которая может быть полезным примеромкто-то другой использует тот же API-интерфейс с помощью интерфейса C # P / Invoke.

Ваши подписи для midiInOpen и обратного вызова немного ошибочны (но не вызовут этой проблемы).Они должны быть:

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

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

т.е. использовать: указатель, где документы API используют DWORD_PTR

0 голосов
/ 18 декабря 2016

Посмотрите на https://github.com/arirusso/midi-winmm/blob/master/lib/midi-winmm/map.rb

О!Это часть твоего.Здорово.Это работает.

Я знаю, что это работает в Windows, потому что я попробовал это.Мое самое большое желание - найти документацию от Microsoft для API winmm.dll.который, как мне кажется, я нашел благодаря тому, что на ваш вопрос ответил user186057.

...