0

我一直在使用《实用红宝石宝石》一书。它给了我下面的代码,我写在:

require 'dl/import'
class LiveMIDI
ON = 0x90
OFF = 0x80
PC = 0xC0
  def initialize
    open
  end
  def noteon(channel, note, velocity=64)
    message(ON | channel, note, velocity)
  end
  def noteoff(channel, note, velocity=64)
    message(OFF | channel, note, velocity)
  end
  def programchange(channel, preset)
    message(PC | channel, preset)
  end
  module C
    extend DL::Importer
    dlload '/System/Library/Frameworks/CoreMIDI.framework/Versions/Current/CoreMIDI'
    extern "int MIDIClientCreate(void *, void *, void *, void *)"
    extern "int MIDIClientDispose(void *)"
    extern "int MIDIGetNumberOfDestinations()"
    extern "void * MIDIGetDestination(int)"
    extern "int MIDIOutputPortCreate(void *, void *, void *)"
    extern "void * MIDIPacketListInit(void *)"
    extern "void * MIDIPacketListAdd(void *, int, void *, int, int, int, void *)"
    extern "int MIDISend(void *, void *, void *)"
  end
  module CF
    extend DL::Importer
    dlload '/System/Library/Frameworks/CoreFoundation.framework/Versions/Current/CoreFoundation'
    extern "void * CFStringCreateWithCString (void *, char *, int)"
  end
  def open
    client_name = CF.CFStringCreateWithCString(nil, "RubyMIDI", 0)
    @client = DL::PtrData.new(nil)
    C.mIDIClientCreate(client_name, nil, nil, @client.ref);

    port_name = CF.cFStringCreateWithCString(nil, "Output", 0)
    @outport = DL::PtrData.new(nil)
    C.mIDIOutputPortCreate(@client, port_name, @outport.ref);

    num = C.mIDIGetNumberOfDestinations()
    raise NoMIDIDestinations if num < 1
    @destination = C.mIDIGetDestination(0)
  end

  def close
    C.mIDIClientDispose(@client)
  end

  def message(*args)
    format = "C" * args.size
    bytes = args.pack(format).to_ptr
    packet_list = DL.malloc(256)
    packet_ptr  = C.mIDIPacketListInit(packet_list)
    # Pass in two 32 bit 0s for the 64 bit time
    packet_ptr  = C.mIDIPacketListAdd(packet_list, 256, packet_ptr, 0, 0, args.size, bytes)
    C.mIDISend(@outport, @destination, packet_list)
  end
end

当我尝试运行它时,我收到以下错误,我不明白,我以前从未使用过 DL。:

livemidi.rb:36:in `open': undefined method `cFStringCreateWithCString' for LiveMIDI::CF:Module (NoMethodError)
    from livemidi.rb:7:in `initialize'
    from livemidi.rb:63:in `new'
    from livemidi.rb:63:in `<main>'

为什么是这样???我在 Mac OS X 上使用 Ruby 1.9.3 你能帮我修复这个错误吗?

4

2 回答 2

0

如果您搜索 Apple 开发人员文档,您会发现一个名为CFStringCreateWithCString. 的方法签名与CFStringCreateWithCString您定义的不同。正确的方法定义是。

CFStringRef CFStringCreateWithCString (
   CFAllocatorRef alloc,
   const char *cStr,
   CFStringEncoding encoding
);

这意味着你应该改变。

extern "void * CFStringCreateWithCString (void *, char *, int)"

到。

extern "CFStringRef CFStringCreateWithCString(CFAllocatorRef, const char*, CFStringEncoding)"
于 2012-05-03T00:00:29.780 回答
0

您的问题似乎是您正在调用cFStringCreateWithCString,但是调用了该函数CFStringCreateWithCString-大写很重要。

于 2012-05-03T00:08:42.443 回答