2012-05-02 121 views
0

我一直用书实用的Ruby宝石。它给了我下面的代码,我写了:未定义的方法,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上 你能帮我修复这个bug吗?

+0

应该是显而易见的,不存在所谓的'CFStringCreateWithCString'方法。 – 2012-05-02 23:34:34

回答

0

如果你搜索苹果开发者文档,你会发现一种称为CFStringCreateWithCStringCFStringCreateWithCString的方法签名与您定义的方法签名不同。正确的方法定义是。

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

这意味着你应该改变。

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

到。

extern "CFStringRef CFStringCreateWithCString(CFAllocatorRef, const char*, CFStringEncoding)" 
0

你的麻烦似乎是你打电话cFStringCreateWithCString,但功能被称为CFStringCreateWithCString - 资本是非常重要的。

+0

虽然第36行确实调用了'CFStringCreateWithCString'。 – 2012-05-03 01:40:36

+0

@dunsmoreb:错误清楚地显示小写版本,所以他必须粘贴不同版本的代码,而不是错误来自。大写版本确实存在 - 我已经运行了代码并确认了这一点。 – Chuck