Неопределенный метод, MIDI

Я работал с книгой "Практические рубиновые самоцветы". Это дало мне код ниже, в котором я написал:

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>'

Почему это??? Я использую Ruby 1.9.3 в Mac OS X. Можете ли вы помочь мне исправить эту ошибку?

2 ответа

Решение

Если вы будете искать в документации для разработчиков 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)"

Твоя проблема в том, что ты звонишь cFStringCreateWithCString, но функция называется CFStringCreateWithCString - капитализация важна.

Другие вопросы по тегам