Неопределенный метод, 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
- капитализация важна.