2014-09-27 5 views
0

OSX 10.8에서 컴파일 할 때 아래 코드가 왜 링크되지 않습니까? 어떻게 10.8과 10.9에서 작동 할 수 있도록 링크를 만들 수 있습니까? 나는 clang ++ 5.1을 사용하고 있습니다.weak_import가 링커 오류를 생성합니다.

// MyFile.cc 
// Compile with: clang++ MyFile.cc -framework ApplicationServices 

#include <ApplicationServices/ApplicationServices.h> 
#include <iostream> 

extern "C" CFStringRef kAXTrustedCheckOptionPrompt __attribute__ ((weak_import)); 
extern "C" Boolean AXIsProcessTrustedWithOptions (CFDictionaryRef options) __attribute__ ((weak_import)); 

static bool IsSupported (void) 
{ 
    return AXIsProcessTrustedWithOptions ? 
     AXIsProcessTrustedWithOptions (NULL): 
     AXAPIEnabled() || AXIsProcessTrusted(); 
} 

int main (void) 
{ 
    std::cout << (IsSupported() ? "SUPPORTED\n" : "NOT SUPPORTED\n"); 
    return 0; 
} 

참고 : 모든 것이 10.9에서 작동하고 10.8에서 진 작품.

답변

1

약한 연결은 여전히 ​​연결이 필요합니다. 링크하는 라이브러리 또는 프레임 워크는 여전히 심볼을 정의해야합니다. 10.8 SDK에서 ApplicationServices 프레임 워크에는 AXIsProcessTrustedWithOptions 기호가 정의되어 있지 않습니다.

나는 기호가 라이브러리에 의해 정의되어야한다는 적어도 두 가지 이유를 생각할 수 있습니다. 첫째, 코드에서 기호 이름에 오타가있는 경우와 같은 오류를 검색합니다. 링커가 기호를 사용할 수 없다는 것을 알리 길 원합니다. 링커와 동적 로더의 두 레벨 네임 스페이스 기능으로 인해 두 번째 (아마도 더 중요한). 동적 라이브러리 또는 프레임 워크에서 제공하는 심볼의 경우 링커는 심볼 이름뿐 아니라 해결 된 라이브러리 또는 프레임 워크를 기록합니다. 로드 할 때 기호는 둘 다 일치합니다. 이렇게하면 두 개의 동적 라이브러리가 충돌이나 잘못된 바인딩의 위험없이 동일한 심볼을 제공 할 수 있습니다.

10.8 SDK에 대해 빌드하고 여전히 조건부로 AXIsProcessTrustedWithOptions()을 사용하려면 동적로드를 사용해야합니다. dlopen()을 사용하여 /System/Library/Frameworks/ApplicationServices.framework/ApplicationServices를 열고 dlsym()을 사용하여 함수에 대한 포인터를 가져옵니다. 포인터가 NULL이 아닌지 확인하고 적절한 유형으로 캐스팅 한 다음 포인터가 가리키는 기능을 호출 할 수 있습니다.

static bool IsSupported (void) 
{ 
    static Boolean (*pAXIsProcessTrustedWithOptions)(CFDictionaryRef options); 

    static dispatch_once_t once; 
    dispatch_once(&once, ^{ 
     void* handle = dlopen("/System/Library/Frameworks/ApplicationServices.framework/ApplicationServices", 0); 
     if (handle) 
      pAXIsProcessTrustedWithOptions = dlsym(handle, "AXIsProcessTrustedWithOptions"); 
    }; 

    return pAXIsProcessTrustedWithOptions ? 
     pAXIsProcessTrustedWithOptions (NULL): 
     AXAPIEnabled() || AXIsProcessTrusted(); 
} 
+0

감사합니다. 저는 Windows 개발자이며 항상이 작업을 수행합니다. 필자는 약한 링크가 자동으로이 작업을 자동으로 수행 할 것이라고 생각했기 때문에 문서가 약간 혼란 스러웠습니다. – Dave

관련 문제