【问题标题】:Help With Ruby FFI帮助 Ruby FFI
【发布时间】:2016-12-18 06:50:31
【问题描述】:

我只是尝试进行一些基本的 Windows 调用来打印来自 MIDI 输入设备(键盘)的信息。这些调用似乎有效,但对 midiInOpen 和 midiInStart 的前两个调用返回 MMSYSERR_NOMEMMMSYSERR_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 {}

【问题讨论】:

  • 问瑞安的问题:我也有同样的问题。 midiInOpen 的结果是 MMSYSERR_NOERROR 并且回调函数在 midiInOpen 之后被准确地调用了一次。然后我调用 midiInStart,结果是 MMSYSERR_INVALHANDLE。您是否发现错误消失了,问题是什么或在 midiInOpen 中设置的正确标志是什么?

标签: ruby ffi


【解决方案1】:

没有明确的答案,因为您的代码看起来基本正确,但我怀疑您传递给 midiInOpen() 的 dwFlags(最后一个参数)是问题所在。看http://msdn.microsoft.com/en-us/library/dd798458(v=vs.85).aspx,好像需要非零。

尝试在 winmm 头文件中查找 CALLBACK_FUNCTION 的值,并在您的模块中声明一个类似的常量,然后将其用作标志参数。

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

即使用 :pointer API 文档使用 DWORD_PTR 的位置

【讨论】:

【解决方案2】:

看看https://github.com/arirusso/midi-winmm/blob/master/lib/midi-winmm/map.rb

哦!那是你的一些。凉爽的。它有效。

我知道这适用于 Windows,因为我已经尝试过了。我最大的愿望是从 Microsoft 那里找到有关 winmm.dll api 的文档。由于user186057回答了您的问题,我认为我已经找到了。

谢谢。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-17
    • 1970-01-01
    • 1970-01-01
    • 2013-11-11
    • 1970-01-01
    相关资源
    最近更新 更多