2012-05-02 1 views
0

나는 Practical Ruby Gems라는 책을 가지고 작업 해왔다. 나는 그것을 실행하려고하면, 내가 이해할 수없는 다음과 같은 오류가, 내가 :미정의 방법, MIDI

전에 DL 함께 일한 적이받을

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 

: 그것은 나에게 내가 쓴 아래의 코드를 주었다

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을 사용하고 있습니다. 이 버그를 해결할 수 있습니까?

+0

분명해야 할 것은'CFStringCreateWithCString' 메서드가 없다는 것입니다. –

답변

0

Apple Developer Documentation을 검색하면 CFStringCreateWithCString이라는 메서드가 있습니다. CFStringCreateWithCString의 메소드 서명은 정의한 것과 다릅니다. 올바른 메소드 정의는 다음과 같습니다.

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

즉, 변경해야 함을 의미합니다.

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

To.

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

귀하의 문제는 cFStringCreateWithCString를 호출하고 있다는 것으로 보인다,하지만 기능은 CFStringCreateWithCString라고 - 총액은 중요하다.

+0

36 번 라인은 'CFStringCreateWithCString'을 호출합니다. –

+0

@dunsmoreb : 오류는 소문자 버전을 명확하게 보여주기 때문에 오류가 발생한 것과 다른 버전의 코드를 붙여야합니다. 대문자 버전은 실제로 존재합니다. 코드를 실행하고 확인했습니다. – Chuck