Universal Binary Programming Guidelines

OSXDEV

Jump to: navigation, 찾기

목차

[편집] Universal Binary Programming Guidelines의 소개

Universal Binary Programming Guidelines은 Universal binary로 실행되는 Mac OS X 어플리케이션을 빌드하거나 수정하려는 경험있는 개발자를 지원하기 위해 기술된 문서입니다. Universal binary는 PowerPC 또는 Intel microprocessor를 사용하는 Macintosh 컴퓨터에서 네이티브하게 실행되며 단일 패키지에서 두개의 아키텍쳐를 위한 최적의 퍼포먼스를 제공합니다.

이번 버전의 Universal Binary Programming Guidelines는 2005년 6월에 열린 Apple Worldwide Developers Conference 이후 업데이트된 내용을 담고 있습니다. 이 문서는 Intel 기반 Macintosh으로 이동해 개발하려는 개발자를 위한 모든 정보를 담고 있습니다. 이 버전은 새롭게 수정된 툴 문서의 내용을 담고 있으며, (Xcode 2.2 User Guide, GCC Porting Guide, Cross-Development Programming Guide) 그리고 또한 보다 향상된 지침과 팁을 제공합니다. 누구라도 이전 버전의 Universal Binary Programming Guidelines문서를 가지고 있다면 이 버전으로 바꿔 참고하시기 바랍니다.

중요: 이것은 개발에서 application binary interface (ABI)를 위한 예비문서입니다. 비록 이 문서가 보다 정확한 기술적인 이해를 위해 작성되었지만, 최종문서는 아닙니다. Apple Computer는 이러한 기술을 채택하거나 프로그래밍 인터페이스를 사용하기 위해 계획한 개발자를 돕기 위해 이 정보를 제공합니다. 이 문서는 수정될 수 있으며, 최종적인 운영체체 소프트웨어와 최종 문서에 의해 테스트된 이 문서에 따라 소프트웨어가 구현되었습니다. 이 문서의 새로운 버전은 향후 ABI의 기초가 될 것입니다. 이 문서나 다른 개발 문서에 대한 최신의 정보는 ADC Reference Library에 제공되는 New & Updated 사이드바를 참고하시기 바랍니다.

이번 섹션에서는 아래의 내용을 다룹니다.

  • 누가 이 문서를 읽어야 하는가 (Who Should Read This Document)
  • 전제 조건 (Assumptions)
  • Convention
  • 이 문서의 구성 (Organization of This Document )


[편집] 누가 이 문서를 읽어야 하는가

이 문서의 대상은 현재 Apple 하드웨어 와 Mac OS X에서 네이티브하게 작동되는 작동되는 응용프로그램을 개발하고 있고, 이것을 어떻게 수정해야 하는 지를 알고싶은 개발자입니다. 아직 Macintoshd용 어플리케이션을 작성해 보지 않은 개발자는 이 문서의 안내에 따라 universal binary가 안정적으로 작동되도록 개발할 수 있습니다.

[편집] 전제 조건

  • 개발된 어플리케이션은 Mac OS X에서 실행됩니다.
    • 어플리케이션의 개발 환경은 모든 Mac OS X의 개발 환경을 사용할 수 있습니다. : Carbon, Cocoa, Java 또는 BSD UNIX
    • 만약 어플리케이션이 UNIX 운영체제에서 작동되나 Mac OS X에서 특수한 환경을 요구하지 않는다면 Porting UNIX/Linux Applications to Mac OS X을 먼저 읽어 보시기 바랍니다. </i>Porting UNIX/Linux Applications to Mac OS X</i>의 위치는 ADC Home > Reference Library > Documentation > Darwin > Porting > Porting UNIX/Linux Applications to Mac OS X 입니다.
    • 만약 응용프로그램이 Windows 운영체제에서만 작동된다면 Porting to Mac OS X from Windows Win32 API를 먼저 읽어보시기 바랍니다. Porting to Mac OS X from Windows Win32 API의 위치는 ADC Home > Reference Library > Documentation > Porting > Windows > Porting to Mac OS X from Windows Win32 API 입니다.
    • 만약 Mac OS X을 처음 사용한다면, </i>Mac OS X Technology Overview</i>를 먼저 읽어보시기 바랍니다. Mac OS X Technology Overview의 위치는 ADC Home > Reference Library > Documentation > Mac OS X > Mac OS X Technology Overview 입니다.
  • 만약 Xcode의 사용법을 알고 싶다면
    • 현재 Xcode는 Intel과 PowerPC에서 실행되는 코드를 컴파일 할 수 있는 유일한 GUI 툴입니다.
    • 만약 Xcode가 익숙하지 않다면 Xcode 2.1 User Guide를 가지고 먼저 사용해 보시기 바랍니다. Xcode 2.2 User Guide의 위치는 ADC Home > Reference Library > Documentation > Tools > Xcode > Xcode 2.2 User Guide 입니다.
    • 만약 CodeWarrior를 사용하고 있다면, </i>Porting CodeWarrior Projects to Xcode</i>를 읽어 보시기 바랍니다. Porting CodeWarrior Projects to Xcode의 위치는 ADC Home > Reference Library > Documentation > Tools > Xcode > Porting CodeWarrior Projects to Xcode 입니다.

[편집] Convention

x86은 이 문서에서 Intel에서 개발된 마이크로프로세서를 통칭하기 위해 일반적으로 사용되는 용어입니다. 이 문서는 x86을 IA-32(Intel Architecture 32-bit)와 동일하게 사용합니다.

[편집] 이 문서의 구성

이 문서는 아래와 같은 챕터들로 구성되어 있습니다.

  • "Building a Universal Binary" 는 네이티브한 Universal Binary를 빌드하기 위한 Xcode를 사용방법과 빌드 옵션을 설명하고, x86 아키텍쳐에서 정상적으로 작동되지 않는 코드에 대한 트러블슈팅 정보를 담고 있습니다.
  • "Architectural Differences" 는 x86과 PowerPC 아키텍쳐간의 큰 차이점을 대략적으로 설명합니다. 이러한 차이점을 이해하면, 보다 손 쉽게 코드를 포팅할 수 있습니다.
  • "Swapping Bytes"는 byte ordering 는 세부적인 차이점을 설명하며, byte swapping routines의 리스트에 대비하고, byte swapping에 필요한 여러 시나리오에 대한 전략에 대해 논의합니다. 이것은 모든 Mac OS X 개발자들이 읽어야 하며, 양쪽의 아키텍쳐사이에서 데이터와 데이터파일을 이동알 때 byte-ordering 이슈를 어떻게 피할 것인 지 알려줄 것입니다.
  • "Guidelines for Specific Scenarios" 는 대부분의 어플리케이션의 일반적이지 않은 상황에 대한 다양한 팁을 담고 있습니다.
  • "Preparing Vector-Based Code" 는 높은 퍼포먼스 컴퓨팅을 필요로 하는 개발자들을 위한 다양한 옵션에 대해 논의합니다.

이 문서는 아래와 같은 부록들을 담고 있습니다.

  • "Rosetta" 는 Intel 기반 Macintosh 컴퓨터에서 PowerPC binary 수행하는 translation process를 설명합니다.
  • “Architecture-Independent Vector-Based Code” 는 아키텍쳐에 의존하는 최소의 코드를 이용해 벡터 코드를 작성하는 방법을 보여주는 예제를 통해 매트릭스 곱셉연산을 설명합니다.
  • "Application Binary Interface"는 IA-32 ABI에 대해 논의하며 세부 정보를 제공합니다.
  • “Using PowerPlant” 는 Intel 기반 Macintosh에서 PowerPlant를 사용위해 만들어야 하는 변경된 점들에 대해 논의합니다.


[편집] Universal Binary 빌드하기

어플리케이션을 빌드하고 Intel 마이크로프로세서를 사용하는 Macintosh 에서 네이티브로 실행하는 경우, Intel과 PowerPC 마이크로프로세서를 사용하는 Macintosh 컴퓨터 사이의 아키텍져적으로 다른점은 PowerPC 코드가 존재히는 것 때문에 다르게 작동될 수 있다는 것입니다. 아키텍쳐적인 차이가 어플레이케이션 코드에 영향을 주는 범위는 소스 코드 수준입니다. 대부분 존재하는 코드는 특정 프로세서와 무관한 high-level의 소스 코드입니다. 만약 응용프로그램이 이러한 범위에 있다면, 일부분에서 Universal binary로 조정된 코드를 포함하는 것을 발견할 수 있습니다. Mac OS 9에서 Mac OS X으로 포팅한 카본 개발자보다, 코코아 개발자는 약간의 최적화하는 방법을 알고 있어야 합니다.

high-level 프레임워크를 사용하고 Mac OS X 10.4에서 GCC 4.0으로 빌드한 대부분의 코드는 Intel 기반 Macintosh에서 달라진 점을 약간 포함합니다. (만약 있다면) 이러한 상황에서 모든 개발자에 대한 매우 좋은 접근 방법은 Universal binary로 빌드하고(이번장에서 설명하는 것처럼) 응용프로그램이 어떻게 동작하는 지 확인해 보는 것입니다. 의도했던 것처럼 코드가 작동하지 않는 부분을 찾아본 후, 이 문서에서 해당하는 문제점을 확인해 보시기 바랍니다.

코드 내부에 AltiVec 명령어를 사용하거나 최적화나 다른 목적으로 아키텍쳐적으로 다른 점을 사용하는 개발자는 대부분의 코드를 수정할 필요가 있습니다. 아마도 이러한 개발자는 universal binary로 빌드하기 전에 이 문서를 참고하려 할 것입니다. AltiVec 프로그래머는 이 문서의 "Preparing Vector-Based Code" 를 읽어 보시기 바랍니다.

이번 장에서는 universal binary를 생성하기 위해 Xcode 2.2 버전을 사용하는 방법을 설명하며, 문제점에 대한 해결 방안, 적절한 빌드 옵션을 알려드립니다. Intel 기반 Macintosh의 소프트웨어 개발 워크플로우를 확인하실 수 있으며, 이것은 Power-PC 기반 Macintosh의 소프트웨어 개발 워크플로우와 같습니다.

여기에서는 다음의 내용을 다룹니다.

  • 빌드 전제조건 (Build Assumptions)
  • 코드 빌드하기 (Building Your Code)
  • 디버깅 (Debugging)
  • 문제점 해결 (Troubleshooting Your Built Application)
  • Binary가 Universal인지 확인하기 (Determining Whether a Binary is Universal)
  • 빌드 옵션 (Build Options)
  • 참고 사항 (See Also)


[편집] 빌드 전제조건 (Build Assumptions)

어플리케이션을 universal binary로 빌드하기전 아래의 사항이 필요합니다.

  • 어플리케이션은 Mac OS X용으로 이미 빌드되어 있어야합니다. 어플리케션 개발은 모든 Mac OS X 개발 환경을 사용할 수 있습니다. (Carbon, Cooca, Java, BSD UNIX)
  • 어플리케이션은 Mach-O 실행 포맷을 사용해야 합니다. Mach-O 바이너리는 Intel 기반 Macintosh에서 네이티브하게 실행되는 유일한 바이너리 타입입니다. 만약 이미 Xcode 컴파일러와 링커를 사용하고 있다면, 어플리케이션의 바이너리는 Mach-O 바이너리입니다. Code Fragment Manager기반의 Carbon 어플리케이션의 Preferred Executable Format (PEF)은 Mach-O로 전환해야 합니다.
  • Xcode의 target은 native Xcode target이어야 합니다. 만약 아니라면 Xcode에서 Project > Upgrade All Targets in Project to Native를 선택할 수 있습니다.
  • 코드 프로젝트는 GCC 4.0으로 포팅되어야 합니다. Xcode는 Intel 기반 Macintosh target에 대해 GCC 4.0을 사용합니다. 만약 프로젝트내에 사용되는 코드가 GCC 4.0용으로 변경해야 한다면 GCC Porting Guid을 참고하시기 바랍니다. 이 문서의 위치는 ADC Home > Reference Library > Documentation > Tools > Compilers & Debuggers > GCC Porting Guide 입니다.
  • Mac OS X v10.4 universal SDK를 설치해야 합니다. SDK 인스톨러의 위치는 /Developer/SDKs/MacOSX10.4u.sdk입니다.


[편집] 코드 빌드하기 (Building Your Code)

PowerPC 기반 Macintosh에서 어플리케이션을 빌드하기 위해 Xcode를 사용하고 있다면, Intel 기반 Macintosh에서 코드를 빌드하는 것이 같은 방법으로 수행된다는 것을 알 수 있습니다. 기본적으로 Xcode는 (2.1 부터) Xcode 프로젝트가 빌드된 아키텍쳐에서 실행하기 위한 코드를 컴파일합니다.

 : CodeWarrior 사용자는 Xcode와 CodeWarrior 간의 비슷한 점과 차이점을 확인하기 위해 Xcode from a CodeWarrior Perspective를 읽어봐야 합니다. Xcode from a CodeWarrior Perspective의 위치는 ADC Home > Reference Library > Documentation > Tools > Xcode > Porting CodeWarrior Projects to Xcode 입니다. 이 정보는 당신의 CodeWarrior 경험을 Xcode에서 활용할 수 있도록 도와드릴 수 있습니다.

프로젝트를 개발하는 순서는 Default 와 Debug configurations에 다음과 같은 설정을 해야 합니다.

  • 아키텍쳐 세팅은 $(NATIVE_ARCH)을 유지합니다.
  • Mac OS X Deployment Target은 Mac OS X 10.4로 변경합니다.
  • SDKROOT 설정은 /Developer/SDKs/MacOSX10.4u.sdk로 합니다.

프로젝트에 아래의 순서에 따라 SDK 루트를 설정할 수 있습니다.

  1. 버전 2.2 이상의 Xcode에서 프로젝트를 엽니다. Xcode의 target은 native target으로 설정되어 있어야 합니다. 만약 아니라면 Project > Upgrade All Targets in Project to Native를 선택할 수 있습니다.
  2. Groups & Files 목록에서 프로젝트 이름을 선택합니다.
  3. Info 버튼을 눌러 Info 윈도우를 엽니다.
  4. Info 윈도우의 General 탭을 선택하고, Cross-Develop Using Target SDK 팝업 메뉴에서 Mac OS X 10.4 (Universal) 를 선택합니다. 만약 Mac OS X 10.4 (Universal)을 선택할 수 없다면 /Developer/SDKs에서 universal SDK인 MacOSX10.4u.sdk 가 설치되어 있는 지 확인합니다. 없다면 이 SDK를 설치하신 후 진행하시기 바랍니다.
  5. 현재 쉬트에서 Change를 클릭합니다.

Debug build configuration은 Zero Link와 Fix and Continue, debug-symbol generation 옵션은 켜고 코드 최적화는 끕니다. 하나의 아키텍쳐에서 빌드된 디버그 바이너리를 다른 아키텍쳐에서 실행할 수 없다는 것을 항상 염두에 두시기 바랍니다.

양쪽의 아키텍쳐에서 어플리케이션을 테스트할 준비가 되면, Release configuration을 사용하고 싶을겁니다. 이 설정은 ZeroLink 와 Fix and Continue의 체크를 풉니다. 또한 Code-optimization 수준을 기본적으로 높게 설정합니다. Default and Debug configurations에서 처럼 Mac OS X Deployment Target을 Mac OS X 10.4으로 설정하고 SDK root 는 MacOSX10.4u.sdk를 사용합니다. universal binary를 빌드하기 위해서는 Release configuration에 대한 아키텍쳐 설정은 Intel 과 PowerPC로 빌드하기 위해서 설정해야 합니다.

아래의 방법을 따라 아키텍쳐 설정을 변경할 수 있습니다.

  1. 버전 2.2 이상의 Xcode에서 프로젝트를 엽니다.
  2. Groups & Files 목록에서 프로젝트 이름을 선택합니다.
  3. Info 버튼을 눌러 Info 윈도우를 엽니다.
  4. Info 윈도우의 Build 탭을 선택하고 (그림 1-1), Configuration 팝업에서 Release를 선택합니다.
  5. 설정사항 중 Architectures을 찾아 두번 클릭합니다.
  6. 설정 변경 쉬트가 나타나면 그림 1-2와 같이 PowerPC 와 Intel 옵션을 선택하고 OK를 클릭합니다.
  7. Info 윈도우를 닫습니다.
  8. 빌드하고 프로젝트를 실행합니다.

그림 1-1 : Build pane
그림:A_universal_guidelines_Info_styles.gif

그림 1-2 아키텍쳐 설정
그림:A_universal_guidelines_Build_options.gif

만약 빌드되지 않는다면 "디버깅(Debugging)"을 참고하시기 바랍니다.

만약 어플리케이션이 빌드 되었으나 Intel 기반 Macintosh에서 네이티브 바이너리로 실행할 때, 어플리케이션이 기대했던 대로 실행되지 않을 경우, 아래의 문제점 해결 (Troubleshooting) 부분을 참고합니다.

의도했던 대로 어플리케이션이 실행된다고 해서 다른 아키텍쳐에서도 동작할 것이라고 추측하지는 마십시오. 어플리케이션은 Intel 기반 Macintosh와 PowerPC Macintosh 모두에서 테스트해야 합니다. 만약 어플리케이션이 디스크에서 데이터를 읽어 디스크로 데이터를 쓰는 경우 하나의 아키텍쳐에서 파일을 저장할 수 있는지 그리고 다른 아키텍쳐에서 정상적으로 열리는 지 확인해야 합니다.

참고 : Xcode는 모든 아키텍쳐 SDK를 지원할 수 있습니다. 예를 들어 PowerPC용 Mac OS X v10.3을 target으로 하면서 Intel용 Mac OS X v10.4.1을 target으로 할 수 있습니다.

기본 컴파일러 세팅, 특정 아키텍쳐에 대한 옵션, autoconf macro에 대한 정보는 아래의 빌드 옵션 (Build Options)을 보시기 바랍니다.

Intel 기반 Macintosh용으로 이전하는 동안 PowerPC에 대한 특정 버전의 SDK (Mac OS X v10.3, v10.2등)를 가지고 빌드하는 것에대한 정보는 다음의 리소스를 참고하시기 바랍니다.

  • Xcode 2.2 User Guide의 Using Cross Development in Xcode를 참고하시기 바랍니다. Xcode 2.1 User Guide의 위치는 ADC Home > Reference Library > Documentation > Tools > Xcode > Xcode 2.2 User Guide 입니다.
  • Cross-Development Programming Guide의 Cross Development and Universal Binaries는 Intel 기반과 Power-PC 기반 Macintosh 모두를 위한 object 코드를 담은 실행 가능한 파일을 생성하는데 자세한 내용을 확인할 수 있습니다. Cross-Development Programming Guide의 위치는 ADC Home > Reference Library > Documentation > Tools > Xcode > Cross-Development Programming Guide입니다.

[편집] 디버깅 (Debugging)

Xcode는 디버깅을 위해 GDB를 사용하며, Xcode 2.2 User Guide의 Debugging 에서 자세한 내용을 찾아 볼 수 있습니다. Xcode 2.2 User Guide의 위치는 ADC Home > Reference Library > Documentation > Tools > Xcode > Xcode 2.2 User Guide 입니다. Xcode는 코드를 확인할 때 브레이크 포인트를 걸고 변수, 스택 프레임, 쓰레드를 확인하기 위한 GDB용으로 강력한 유저 인터페이스를 제공합니다.

"Debugging with GDB" (GDB를 사용하기 위한 오픈소스 문서)는 개발자들이 참고할 수 있는 또 다른 리소스입니다. Debugging with GDB의 링크는 http://developer.apple.com/documentation/DeveloperTools/gdb/gdb/gdb_toc.html 입니다. 이 문서는 많은 변수 정보와 디버깅에 대한 브레이크 포인트의 리스트를 어떻게 얻을 수 있는 지 설명되어 있습니다.

만약 코드를 GCC4.0으로 옮길 경우, 대부분의 링크 오류와 컴파일러의 경고에 대한 해결책은 GCC Porting Guide에서 확인할 수 있습니다. GCC Porting Guide의 위치는 ADC Home > Reference Library > Documentation > Tools > Compilers & Debuggers > GCC Porting Guide 입니다. GCC 옵션에 대한 추가 정보는 GNU C/C++/Objective-C 4.0.1 Compiler User Guide의 3.8절에서 찾아 보실 수 있습니다. GNU C/C++/Objective-C 4.0.1 Compiler User Guide의 위치는 http://developer.apple.com/documentation/DeveloperTools/gcc-4.0.1/gcc/index.html 입니다.

[편집] 문제점 해결 (Troubleshooting Your Built Application)

아래와 같은 대부분의 일반적인 작동 문제는 Intel 기반 Macintosh에서 네이티브로 실행하는 경우 확인할 수 있습니다.

  • 어플리케이션 충돌
  • 예측하지 못한 계산상 오류
  • 부정확한 디스플레이 컬러
  • 텍스트가 바르게 표시되지 않음 - *Last Resort font>http://developer.apple.com/fonts/LastResortFont/* 캐릭터가 표시되거나 예상치 않게 중국어나 일본어가 표기되는 경우
  • 파일을 정확하게 읽고 쓸 수 없는 경우
  • 네트워크간의 전송이 부정확한 경우

처음의 두 가지 문제는 일반적으로 아키텍쳐에 의존하는 코드로부터 문제가 발생됩니다. Intel 마이크로프로세서를 사용하는 Macintosh에서 정수를 0으로 나눌 경우 crash가 발생하지만, PowerPC의 경우 같은 상황에서는 0을 리턴합니다. 이러한 경우, 코드는 아키텍쳐에 의존하는 형태로 재작성되어야 합니다. 이 문서의 Architectural Differences는 PowerPC와 Intel 마이크로 프로세서를 사용하는 Macintosh컴퓨터 간의 큰 차이점에 대해 설명하며, 여기에서는 어떤 코드가 crach를 발생하거나 또는 예측하지 못한 계산상의 오류를 유발하는 지 찾을 수 있도록 알려드립니다.

나머지 4가지는 대부분 아키텍쳐간의 byte-ordering 으로 인해 종종 발생합니다. 이러한 문제는 데이터를 읽고 쓰는 경우 byte order를 확인하여 쉽게 해결할 수 있습니다. byte ordering을 핸들링하는 효과적인 방법은 이 문서의 Swapping Bytes를 지원하는 것입니다. Mac OS X은 주고받는 모든 것에 대해 byte-ordering이 정확하도록 보장한다는 것을 염두에 두시기 바랍니다. Apple이 정의한 리소스는(메뉴와 같은) 문제를 발생하지 않습니다. 하지만 다른 개발 업체 혹은 개인 개발자가 작성한 커스텀 리소스는 문제가 발생할 수있습니다.

Apple 엔지니어는 Intel 마이크로프로세서를 사용하는 Macintosh에서 네이티브로 실행되는 많은 코드를 준비했습니다. (운영체제, 대부분의 애플 어플리케이션, 애플이 개발한 툴등...) 이 문서의 안내는 이러한 작업의 결과입니다. 추가로 더 많은 논의들은 이 문서의 Architectural Differences 와 Swapping Bytes에 소개되어 있으며, 엔지니어들이 주의깊게 살펴본 이슈들입니다. 이러한 것은 이 문서의 Guidelines for Specific Scenarios에 설명되어있습니다. 이러한 내용들을 훑어본다면 좋은 정보를 얻을 수 있습니다.

[편집] 바이너리가 Universal인지 확인하기 (Determining Whether a Binary is Universal)

응용프로그램이 universal binary를 가지고 있는지는, 해당 어플리케이션을 선택한 후 Cmd-I를 눌러 정보 입수를 통해 확인하실 수 있습니다. 어플리케이션 정보 윈도우의 More Info 에는 바이너리가 Intel 인지 PowerPC 인지 아니면 양쪽 모두를 지원하는 지에 대한 아키텍쳐 엔트리가 표시되어 있습니다. (그림 1-3)

그림 1-3 체스 어플리케이션의 아키텍쳐 엔트리는 Intel, PowerPC입니다.
그림:A_universal_guidelines_Chess.gif

Intel 기반 Macintosh에서 네이티브 아키텍쳐에 대한 실행코드를 포함하지 않은 어플리케이션일지라도 실행될 수 있습니다. 물론 실행여부는 어플리케이션과 Rosetta와의 호환성에 의존합니다. 더 많은 정보는 이 문서의 Rosetta를 확인하시기 바랍니다.

[편집] 빌드 옵션 (Build Options)

여기에서는 Intel 마이크로프로세서를 사용하는 Macintosh에서 Xcode 2.1을 사용할 때 알아두어야 할 빌드 옵션에 대한 정보를 담고 있습니다. 이 리스트는 디폴트 컴파일러 옵션이며, 특정 아키텍쳐에 대해 어떻게 옵션을 설정할 수 있는지 설명하며, autoconf macros를 사용하는 정보도 소개합니다.

여기에서는

  • 디폴트 컴파일러 옵션 (Default Compiler Options)
  • 특정 아키텍쳐 옵션 (Architecture-Specific Options)
  • Autoconf Macros

디폴트 컴파일러 옵션 Intel 마이크로프로세서를 사용하는 Macintosh에서 Xcode 2.1인 경우, 표준 GCC 배포판과 다른 컴파일러 플래그에 대한 기본값이 아래의 표에 정리되어 있습니다.

표 1-1 : Intel 마이크로프로세서를 사용하는 Macintosh에서 컴파일러 플래그에 대한 기본값

Compiler Flag Default Value 특징
-mfpmath sse 부동소수점 연산에 SSE 사용
-msse2 기본 Intel instruction set architecture에서 MMX™, SSE, SSE2 확장을 사용

특정 아키텍쳐 옵션 (Architecture-Specific Options) 대부분의 개발자는 어플리케이션 개발시 특정 아키텍쳐 설정을 사용할 필요가 없습니다. Intel 기반 Macintosh에 대한 플래그와 PowerPC를 위한 다른 플래그를 설정하기 위해 Xcode에서는 특정 아키텍쳐 설정을 지원하기 위한 PER_ARCH_CFLAGS_i386 와 PER_ARCH_CFLAGS_ppc 빌드 설정을 사용할 수 있습니다. 예를 들어 -faltivec과 -msse3 를 지원하기 위해 다음과 같은 빌드를 설정할 수 있습니다.

PER_ARCH_CFLAGS_i386 = -msse3
PER_ARCH_CFLAGS_ppc = -faltivec

유사하게 OTHER_LDFLAGS_i386 과 OTHER_LDFLAGS_ppc 빌드 설정을 사용해 특정 아키텍쳐의 링커 플래그를 지원할 수 있습니다. 예를들어 gcc, ld등에 -arch 플래그를 전달할 수 있습니다. 사용가능한 값은 i386과 ppc입니다. 양쪽 모두를 지정하고 싶은 경우는 아래와 같이 사용합니다.

-arch ppc -arch i386

특정 아키텍쳐에 대한 더 많은 정보는 Xcode 2.2 User Guide 의 Building Universal Binaries 를 참고하시기 바랍니다. Xcode 2.2 User Guide의 위치는 ADC Home > Reference Library > Documentation > Tools > Xcode > Xcode 2.2 User Guide입니다.

Autoconf Macros 만약 Autoconf를 사용여 프로젝트를 컴파일하고 PowerPC와 Intel 기반 Macintosh 컴퓨터 모두에 대해 빌드하고 싶다면, 프로젝트의 configure에서 런타임 시스템의 엔디안 타입을 결정하기 위한 autoconf macros 를 사용하지 말아야 합니다. 예를 들어 만약 프로젝트에서 autoconf AC_C_BIGENDIAN macro를 사용한다고 가정한다면, 프로젝트를 생성 후 어느 한쪽을 타겟으로 빌드한 경우 다른 아키텍쳐에서 실행할 때 프로그램이 정상적으로 작동하지 않습니다. PowerPC 와 x86 아키텍쳐 모두에 대해 정확하게 빌드하는 방법은, 코드 내에서 컴파일러에 정의된 __BIG_ENDIAN__ 과__LITTLE_ENDIAN__ 매크로를 사용하는 것입니다.

더 많은 정보는 Porting UNIX/Linux Applications to Mac OS X의 Using GNU Autoconf 를 참고하시기 바랍니다. Porting UNIX/Linux Applications to Mac OS X의 위치는 ADC Home > Reference Library > Documentation > Darwin > Porting > Porting UNIX/Linux Applications to Mac OS X 입니다.

[편집] 참고사항 (See also)

아래의 리소스는 응용프로그램을 컴파일하고 빌드하기 위한 관련된 정보를 제공하며, 퍼포먼스를 측정합니다.

  • Xcode 2.2 User Guide는 모든 Xcode 프로젝트 형태에 대해 컴파일과 디버그에 필요한 모든 명령어를 담고 있습니다. (C, C++, Objective C, Java, AppleScript, resource, nib files등..) 이 문서의 위치는 ADC Home > Reference Library > Documentation > Tools > Xcode > Xcode 2.2 User Guide 입니다.
  • GCC Porting Guide는 코드를 GCC 4.0과 호환될 수 있도록 수정하는 방법을 제공합니다. GCC Porting Guide의 위치는 ADC Home > Reference Library > Documentation > Tools > Compilers & Debuggers > GCC Porting Guide 입니다.
  • C++ Runtime Environment Programming Guide는 Panther 10.3.9와 이후 버전의 GCC 4.0에서 공유되는 C++ 런타임에 대한 자세한 정보를 제공합니다. C++ Runtime Environment Programming Guide의 위치는 ADC Home > Reference Library > Documentation > Tools > Compilers & Debuggers > C++ Runtime Environment Programming Guide
  • Porting UNIX/Linux Applications to Mac OS X. Porting UNIX/Linux Applications to Mac OS X의 위치는 ADC Home > Reference Library > Documentation > Darwin > Porting > Porting UNIX/Linux Applications to Mac OS X 입니다. UNIX와 Linux 어플리케이션을 universal binary로 포팅하려는 개발자는 Compiling for Multiple Architectures 절을 확인하시기 바랍니다.
  • Kernel Extension Concepts은 Intel 기반 Macintosh 컴퓨터에서 KEXTs를 디버깅하는 방법을 설명합니다. Kernel Extension Concepts의 위치는 ADC Home > Reference Library > Documentation > Darwin > Kernel > Kernel Extension Concepts 입니다.
  • Performance tool. /Developer 디렉터리에 있는 Shark, MallocDebug, ObjectAlloc, Sampler, Quartz Debug, Thread Viewer, 그리고 다른 Apple이 개발한 툴 (일부 command-line, 다른 것은 GUI를 사용) Command-line performance tools은 /usr/bin 디렉터리입니다.
  • Code Size Performance GuidelinesCode Speed Performance Guidelines는 Mach-O 실행코드에 대해 효과적인 최적화를 알려드립니다. Code Size Performance Guidelines의 위치는 ADC Home > Reference Library > Documentation > Performance > Tools > Code Size Performance Guidelines 이며 Code Speed Performance Guidelines의 위치는 ADC Home > Reference Library > Documentation > Performance > Tools > Code Speed Performance Guidelines 입니다.

[편집] 아키텍쳐적으로 다른점(Architectural Differences)

PowerPC와 x86 아키텍쳐는 하나의 아키텍쳐에 대해 컴파일된 코드가 다른 아키텍쳐에서 적당하게 실행될 수 있도록 예방할 수 있는 기본적으로 다른 몇가지가 있습니다. Intel 마이크로프로세서를 사용하는 Macintosh에서 네이티브하게 실행되도록 변경이 필요한 PowerPC 코드의 범위는 CPU에 의존적으로 작성된 코드의 양에 따라 다릅니다. 여기에서는 두 아키텍쳐간의 크게 다른 점을 순서대로 살펴봅니다. 변경에 대해 의문이 생기는 코드를 확인할 수 있는 정보로 사용할 수 있습니다.

여기에서는 아래의 내용을 다룹니다.

  • Alignment
  • Bit Fields
  • Byte Order
  • 호출 규약 (Calling Conventions)
  • 데이터 타입 변환 (Data Type Conversions)
  • 데이터 타입 (Data Types)
  • 0으로 나누는 연산 (Divide-By-Zero Operations)
  • 부동소수점 연산과 동등한 비교 (Floating-Point Equality Comparisons)
  • Structures 와 Unions (Structures and Unions)
  • 참고 사항 (See Also)

[편집] Alignment

모든 PowerPC 명령어는 명령어당 4바이트이며 항상 네 바이트씩 정렬되어야 합니다. x86 명령어는 가변적인 크기이며 (1에서 10이상의 바이트) 결과가 정렬될 필요는 없습니다.

[편집] Bit Fields

부호가 있는 변수는 0또는 1을 갖는 1비트의 비트필드를 가지며, 컴파일러, 아키텍쳐, 최적화, 레벨등의 따라 다릅니다. 비트필드에 부호가 있다면 1로 비트 필드의 변수를 비교하는 코드 작동하지 않습니다. 따라서 부호없는 1비트의 비트필드가 필요합니다. 메모리에 비트필드의 순서는 두 아키텍쳐 사이에 변환할 수 있다는 점을 잊지 마시기 바랍니다.

엔디안 포맷과 관련된 문제점에 대한 정보는 이 문서의 "Swapping Bytes", "Archived Bit Fields", "Structures and Unions" 를 보시기 바랍니다.

[편집] Byte Order

마이크로프로세서 아키텍쳐는 메모리에 여러 개 바이트 데이터 포맷중 각각의 바이트를 저정하기 위해 일반적으로 두개의 다른 바이트 순서(little-endian 과 big-endian)가 있습니다. 하나의 컴퓨터에서 생성한 파일을 다른 바이트 순서를 사용하는 컴퓨터에서 파일의 데이터를 읽고 쓴다면 이 차이점은 매우 중요한 문제를 발생시킬 수 있습니다. 따라서 네트워크 연결을 통해 데이터를 주고 받거나 네트워크 데이터를 다루는 경우 바이트 순서에 대해 생각해 봐야 합니다. 이러한 차이점을 중요하게 생각하지 않는다면 바이트 순서의 차이점으로 인해 잘못된 결과를 초래할 수 있습니다. 예를 들어 목록 2-1에서 처럼, 스칼라 타입 메모리의 바이트 순서는 아키텍쳐에 의존적입니다.

목록 2-1 : 바이트 순서 차이를 보여주는 코드

unsigned char charVal;
unsigned long value = 0x12345678;
unsigned long *ptr = &value;
charVal = *(unsigned char*)ptr;

little-endian 어드레싱을 사용하는 프로세서에서 변수 charVal는 0x78을 갖습니다. On big-endian 어드레싱을 사용하는 프로세서에서 변수 charVal는 0x12을 갖습니다..

charVal = (unsigned char)*ptr;

바이트 순서에 대한 보다 상세한 내용과 바이트 순서에 대해 고려할 수 있는 효과적인 방법에 대해서는 이 문서의 "Swapping Bytes"를 보시기 바랍니다.

[편집] 호출 규약 (Calling Conventions)

x86 C 언어에서 호출 규약(Calling Conventions - application binary interface, 또는 ABI)은 함수의 아규먼트가 스택을 통과하도록 규정하고 있습니다. PowerPC ABI는 함수의 아규먼트가 레지스터를 지나도록 명시하고 있습니다. 또한 x86에서는 훨씬 적은 레지스터를 가지고 있으므로, 많은 지역 변수들을 저장하기 위해서는 스택을 사용하고 있습니다. 그러므로 프로그래밍 에러, 지역 변수 배열의 끝을 지나 억세스, 또는 스택에서 부정확하게 변수를 조작하는 작업등은 PowerPC보다 x86시스템에서 더 많은 어플리케이션 충돌이 발생할 수 있습니다.

IA-32 ABI에 대한 더 많은 정보는 Mac OS X ABI Function Call Guide를 보시기 바랍니다. Mac OS X ABI Function Call Guide의 위치는 ADC Home > Reference Library > Documentation > Tools > Compilers & Debuggers > Mac OS X ABI Function Call Guide 입니다. 이 문서는 모든 아키텍쳐에 대해 Mac OS X에서 지원하는 function-calling convention에 대해 설명하고 있습니다. " Application Binary Interface"를 보시기 바랍니다.

[편집] 데이터 타입 변환 (Data Type Conversions)

스트링을 길게 캐스팅하고, 부동소수점 타입을 정수형으로 변환하는 것과 같이 PowerPC와 x86 아키텍쳐는 일부 데이터 타입 변환을 다르게 수행합니다. 시스템이 부동소수점을 정수형으로 바꿀 때, 변수의 소수점 이하를 버립니다. 만약 정수 부분의 값이 정수형으로 표현될 수 없다면 동작은 정의되어 있지 않습니다.

목록 2-2는 아키텍쳐에 의존적인 코드의 예를 보여줍니다. 아키텍쳐에 의존적이지 않도록 코드를 수정할 필요가 있습니다. 목록에서 PowerPC 마이크로프로세서에서는 변수 x가 7fffffff 또는 INTMAX와 같습니다. x86 마이크로프로세서에서는 변수 x가 80000000 또는 INTMIN와 같습니다.

목록 2-2 아키텍쳐에 의존적인 코드

int main (int argc, const char * argv[])
{
    double  a;
    int     x;
    a = 5000000.0 * 6709000.5;  // or any really big value
    x = a;
    printf("x = %08x \n",x);
    return 0;
}

[편집] 데이터 타입 (Data Types)

양쪽 아키텍쳐 모두 long double은 16바이트 입니다. 그러나 Intel 기반 Macintosh 컴퓨터에서는 80비트만이 중요합니다.

x86에서 bool 데이터 타입은 싱글 바이트입니다만 PowerPC에서는 4 바이트입니다. 이 크기의 차이는 alignment 문제를 야기할 수 있습니다. alignment 문제를 피하기 위해서는 고정된 크기의 데이터 타입을 사용해야 합니다. (bool 데이터 타입은 Carbon의 Boolean 타입이 아닙니다. 이것은 1바이트의 고정된 길이입니다.)

양쪽 아키텍쳐에서 같은 형태로 저장되지 않기 때문에, 디스크에 직접 씌여지는 데이터 스트럭쳐의 부분처럼 bool 데이터 타입을 포합하는 문서 포맷은 문제를 발생시킬 수 있습니다. 만약 데이터 스트럭쳐 정의가 Uint32 데이터 타입이나 또 다른 고정된 크기의 4 바이트 데이터 타입을 사용한다면, 비록 알맞게 스왑된 바이트를 변수가 필요로 하지만 스트럭쳐는 옮겨집니다.

[편집] 0으로 나누는 연산 (Divide-By-Zero Operations)

x86 시스템에서 정수를 0으로 나누는 경우 심각한 문제가 발생하며 PowerPC 시스템에서는 0을 리턴합니다. (부동소수를 0으로 나누는 경우도 같은 결과가 나타납니다.) 만약 EXC_I386_DIV 의 crash log를 얻는 다면, 코드의 흐름중 0으로 나눈 연산이 발견된 것입니다. 이 문제를 고치기 위해서는 이러한 작동을 하는 부분을 찾아야 합니다. 0으로 나누는 것을 확인하는 코드를 추가하고 코드를 점검하십시오.

예를들어 이 코드를

int a = b % c;    // Divide by zero can happen here;

이렇게 바꿉니다.

int a;
if (c != 0) {
     a = b % c;
} else {
     a = 0;
}

[편집] 부동소수점 연산과 동등한 비교 (Floating-Point Equality Comparisons)

부동소수점 연산과 동등한 비교 결과는 아키텍쳐 의존적입니다. 물론 컴파일러를 포함하여, 주변 코드, 사용되는 모든 컴파일러 플래그 (부분적으로 최적화 플래그), 현재 쓰레드에 대한 부동소수점 모드등과 같이 비교 작업이 여러 문제와 관련되어 있습니다. 만약 부동소수점 연산 비교가 PowerPC에서 정확하지 않다면, Intel 기반 Macintosh 컴퓨터에서 점검이 필요합니다.

부동소수점 연산 동등 비교 작업을 위해GCC 플래그 -Wfloat-equal를 사용할 수 있습니다. 옵션에 대한 더 자세한 정보는 GNU C/C++/Objective-C 4.0.1 Compiler User Guide의 3.8절을 보시기 바랍니다. GNU C/C++/Objective-C 4.0.1 Compiler User Guide의 위치는 http://developer.apple.com/documentation/DeveloperTools/gcc-4.0.1/gcc/index.html 입니다.

[편집] Structures 와 Unions (Structures and Unions)

스트럭쳐의 필드는 정의된 순서에 따릅니다. 스트럭쳐는 적당한 순서거나 필드명을 직접 억세스합니다.

union이 바이트 순서에 영향을 미치는 컴포넌트를 가질때, 목록 2-3과 같은 유사한 형태를 사용하십시오. wch를 세팅한 코드와 hi와 lo를 읽고 나서 wch의 상위 바이트와 하위 바이트를 정확하게 읽는지 확인합니다. 역으로도 같습니다. 양쪽의 아키텍쳐에서 hi와 lo에 값을 저장한 코드에 wch로부터 정확한 값이 리턴되는 지 확인합니다. 다른 예제는 IntlResources.h에 정의된 WideChar union을 보시기 바랍니다.

목록 2-3 : 바이트 순서에 영향을 줄 수 있는 코드를 가진 union

union WChar{
    unsigned short wch;
    struct {
#if __BIG_ENDIAN__
        unsigned char hi;
        unsigned char lo;
#else
        unsigned char lo;
        unsigned char hi;
#endif
    } s;
}

[편집] 참고 사항 (See Also)

C 프로그래밍 언어에 대한 ISO 표준(ISO/IEC 9899)는 포팅 문제점이나 즉시 확인할 수 없는 많은 문제점에 대한 귀중한 참고서입니다. 다음의 주소에서 많은 참고를 찾아 볼 수 있습니다.

http://www.iso.org/

[편집] 바이트 스왑 (Swapping Bytes)

컴퓨에는 다른 두개의 바이트 순서 방법 (또는 엔디안 포맷)이 있습니다. 엔디안 포맷은 메모리의 멀티바이트로 구성된 숫자 데이터를 구성하는 각각의 바이트를 어떻게 저장할 것인지 지정되어 있습니다. 빅 엔디안 바이트 순서는 멀티바이트 데이터를 저장하는 경우, most significant byte를 맨 앞에 놓아 저장하도록 합니다. 리틀 엔디안 바이트 순서는 least significant byte를 맨 앞에 놓고 저장하도록 규정되어 있습니다. PowerPC 프로세서는 빅 엔디안 바이트 순서이며 x86 프로세서 패밀리는 리틀 엔디안 바이트 순서입니다. 일반적으로 네트워크를 통해 전송되는 멀티 바이트 데이터는 빅 엔디안 바이트 순서를 사용합니다.

만약 어플리케이션이 어느 한가지의 엔디안 포맷을 사용한다고 가정하고 실제 데이터는 다른 것으로 저장한다면, 데이터는 당연히 정확하게 변환될 수 없을겁니다. 어플리케이션에서 멀티바이트 데이터 (16비트, 32비트 또는 64비트)를 읽거나, 멀티 바이트 데이터를 쓰거나, 네트워크로 전송하기 위한 이러한 루틴은 바이트 순서 포맷에 민감합니다. 서로 다른 바이트 순서에 접근하기 위한 일반적인 두가지 방법은 필요할때나 XML또는 다른 바이트 순서에 의존하는 데이터 포맷(예를 들어 코어파운데이션에서 제공하는 CFPreferences, CFPropertyList, CFXMLParser등 )을 사용할 때 바이트를 스왑하는 것입니다.

바이트를 스왑하던지 아니면 바이트 순서에 따르는 데이터 포맷을 사용하는 것은 어플리케이션에서 데이터를 어떻게 사용하는지에 달려있습니다. 만약 지원하려는 파일 포맷이 이미 존재하는 것이라면, 바이너리 호환 솔루션은 어플리케이션에서 빅 엔디안 파일 포맷을 수용하며, 파일을 읽거나 쓸때 사용하기 위한 바이트 스왑 코드를 기록합니다. 만약 지원 파일 포맷이 일반적인 형태가 아니라면 XML, XDR 또는 NSCoding으로 표현되는 데이터를 쓰기 위해 파일 포맷을 새롭게 디자인해야 합니다.

여기에서는 바이트 순서의 문제점에 대해 알아보고, 바이트 스왑에 관한 안내와 Mac OS X에서 가능한 바이트 스왑 API 그리고 바이트 순서 문제에서 대부분의 상황에 대한 해결책을 알려드립니다.

중요 : IP 어드레스의 바이트나 숫자로 여겨지는 데이터는 절대 스왑하지 마십시오. 하지만 결과적으로 중요하지 않을 수도 있습니다. 이 문서의 "IP Addresses and Other “False” Numerical Values"를 보시기 바랍니다.

여기에서는 아래의 내용을 다룹니다.

  • 바이트 순서 문제점이 왜 나타나는가? (Why Byte Ordering Matters)
  • 바이트 스왑 안내 (Guidelines for Swapping Bytes)
  • 바이트 스왑 루틴 (Byte Swapping Routines)
  • 효과적인 바이트 스왑 (Byte Swapping Strategies )
  • 바이트 스왑 데이터에 대한 콜백의 기록과 설치 (Writing and Installing a Callback to Byte Swap Data)
  • 참고 사항 (See Also)

[편집] 바이트 순서 문제점이 왜 나타나는가? (Why Byte Ordering Matters)

여기의 예제는 왜 바이트 순서 문제점이 나타나는가에 대한 실제 문제점을 세부적으로 보여주기 위해 작성되었습니다. 살펴보기위한 C 데이터 스트럭쳐는 목록 3-1에 정의되어 있으며 이것은 4바이트의 정수와 캐릭터 스트링 그리고 두 바이트으 정수로 구성되어 있습니다. 목록은 아래와 같습니다.

목록 3-1 : 멀티 바이트와 싱글 바이트 데이터를 포함하는 데이터 스트럭쳐

typedef struct {
    uint32_t myOptions;
    char     myStringArray [7];
    short    myVariable;
} myDataStructure;
myDataStructure aStruct;
aStruct.myOptions = 0xfeedface;
strcpy(aStruct.myStringArray, "safari");
aStruct.myVariable = 0x1234;

그림 3-1과 비교하면 이 데이터 스트럭쳐가 빅 엔디안과 리틀 엔디안 시스템에서 메모리에 어떻게 저장되는지 보여줍니다. 참고적으로 리틀 엔디안 시스템에서 메모리의 각 데이터 바이트의 주소는 most significant로 부터 least significant로 증가되도록 구성되어 있으며 반대로 빅 엔디안 시스템에서는 least significant에서 most significant로 증가되도록 구성되어 있습니다.

그림 3-1 : 빅 엔디안 바이트 순서와 리틀 엔디안 시스템 비교

  • +byte order.gif+*

그림 3-1에 나타난 내용처럼 아래와 같이 정리됩니다.

  • 그림에 표시된 32비트와 16비트 변수등과 같은 멀티 바이트 데이터는 빅 엔디안과 리틀 엔디안 시스템에서 서로 다르게 저장됩니다. 그림에서 보실 수 있는 것 처럼 빅 엔디안 시스템은 데이터의 most significant byte를 가장 낮은 값을 가지는 주소에 저장합니다. 리틀 엔디안 시스템은 데이터의 most significant byte를 가장 높은 값을 가지는 주소에 저장합니다. 그러므로 빅 엔디안 시스템에서는 myOptions 변수의 (0xce) least significant byte는 메모리의 0x00000003에 저장되며 반대로 리틀 엔디안 시스템에서는 메모리의 0x00000000에 저장됩니다.
  • myStringArray의 char 변수와 같은 싱글 바이트 데이터는 시스템의 바이트 순서 포맷에 상관없이 같은 메모리 위치에 저장됩니다.
  • 각 시스템은 4 바이트 데이터 alignment를 유지하기 위해 바이트를 추가로 붙입니다. 그림에서 추가된 바이트는 가 포함된 음영 부분입니다.

메모리의 멀티 바이트의 바이트 순서는 어떤 시스템의 하나의 아키텍쳐(서로 다른 아키텍쳐를 사용하는 경우)에서 기록된 데이터를 읽고 다시 바이트 단위로 읽는 경우 문제가 됩니다. 예를 들어 어플리케이션이 myOptions 변수의 두번째 바이트에 접근하여 기록하고 나서 다른 바이트 순서 구조를 사용하는 시스템에서 읽으려고 한다면 myOptions의 두번째 바이트의 대신 첫번째 바이트를 얻게됩니다.

리틀 엔디안 시스템에서 생성되고 디스크에 저장된 목록 3-1의 코드로 초기화된 예제 데이터 변수를 가정해 봅시다. 그리고 그 데이터가 바이트 주소 순서로 디스크에 저장되었다고 합시다. 빅 엔디안 시스템에서 디스크로부터 읽을 때, 데이터는 그림 3-1과 같이 메모리에 다시 놓여집니다. 문제는 빅 엔디안 시스템에서 해석된다고 하더라도 데이터가 아직 리틀 엔디안 바이트 순서라는 것입니다. 이러한 다른 점은 정확해야 하는 변수에 문제가 됩니다. 이 예제에서, 필드 myOptions의 변수는 0xfeedface가 되어야 하지만 정확하지 않은 바이트 순서로이기 때문에 0xcefaedfe로 해석됩니다.


노트: 빅 엔디안과 리틀 엔디안 용어는 조나단 스위프트의 걸리버 여행기에서 유래되었습니다. Blefuscu의 제국은 목표는 큰 쪽으로 부터(Big end)로부터 계란을 까 먹는 사람들과 작은 쪽(little end)으로부터 계란을 까 먹는 사람들의 두 파로 나뉘어져 있었습니다.


[편집] 바이트 스왑 안내 (Guidelines for Swapping Bytes)

아래의 가이드라인은 이번 장 이후에 도움이 될 수 있는 효과적인 방법을 제시합니다. 이러한 방법들은 어플리케이션에서 최상의 바이트 스왑 코드를 유지할 수 있도록 도와드립니다.

  • 메모리에 있는 동안 native byte-order에 데이터 스트럭쳐를 유지합니다. 디스크로부터 데이터를 읽거나 디스크로 데이터를 쓰는 경우에만 바이트를 스왑하십시오.
  • 가능하면 컴파일러에게 맡기십시오. 예를 들어, 코어 파운데이션 함수 CFSwapInt16BigToHost와 같은 함수 콜을 사용할 때, 컴파일러는 target에 따라 어떤 함수 콜이 필요한 지 결정합니다. 만약 코드가 아무런 일을 하지 않는다면, 컴파일러는 함수를 콜하지 않습니다. #ifdef를 사용하기 보다는 컴파일러에게 맡기십시오.
  • 만약 큰 파일을 억세스해야 한다면, 실행해야하는 바이트 스왑의 한계에 대해 생각해 보시기 바랍니다. 예를 들어, 파일에서 인접된 자주 억세스하는 데이터를 정렬할 수 있습니다. 그 후에, 전체 데이터 파일에 대신 데이터의 청크에 대해서만 읽거나 바이트 스왑이 필요할 수 있습니다.
  • __BIG_ENDIAN__ 과 __LITTLE_ENDIAN__ 매크로를 사용하십시오. __i386__ 과 __ppc__와 같은 특정 프로세서 타입을 체크하는 매크로는 사용하지 마십시오.
  • 일관된 바이트 오더 접근 방법을 선택하고 , 이것을 고수하십시오. 만약 일반적인 경우 디스크로부터 데이터를 읽거나 쓰는 경우 그것은 사용하기 원하는 엔디안 포맷에 대한 선택입니다. 이것은 데이터의 바이트 오더를 체크하지 않아도 되도록하므로, 가능한난 바이트 오더를 스왑해야 합니다.
  • 어떤 함수가 big-endian 데이터를 리턴한다면, 데이터를 적절한 방법으로 사용하십시오. 이것은 DNSServiceDiscovery 함수중 일부와, (이 포트는 네트워크 바이트 오더입니다.), ColorSync 프로파일 함수를 (모든 데이터는 big-endian) 포함합니다. IconFamilyElement 와 IconFamilyResource 데이터 타입 (IconFamilyPtr 과 IconFamilyHandle 데이터 타입을 포함하는) 항상 big-endian입니다. 다른 많은 함수와 데이터 타입이 있지만 더 이상 나열하지 않겠습니다. API reference 에서 함수의 데이터 리턴 타입 정보를 확인하시기 바랍니다.
  • 스왑하는 바이트가 효율적이도록 유지하여 절대적으로 필요할 경우에만 스왑하십시오.

[편집] 바이트 스왑 루틴 (Byte Swapping Routines)

바이트 스왑 루틴을 지원하는 API의 목록이 아래에 있습니다. 대부분의 경우 프로그래밍을 할때 프레임워크에 매치되는 루틴을 사용하는 데 최고입니다. 코어 파운데이션과 파운데이션 API는 swapping floating-point value에 대한 함수를 가지고 있습니다만 다른 API는 나열하지 않았습니다.

  • POSIX (Portable Operating System Interface) 바이트 오더 함수 (ntohl, htonl, ntohs, 과 htons) 는 man pages에 문서화되어 있으며, Xcode나 터미널을 통해 보실 수 있습니다.
  • Darwin 바이트 오더 함수와 매크로는 헤더파일 libkern/OSByteOrder.h에 정의되어 있습니다. 비록 이 헤더가 커널 프레임워크일지라도, 이것은 high-level 어플리케이션으로부터 사용될 수 있도록 수용할 수 있습니다.
  • 코어 파운데이션 바이트 오더 함수는 헤더파일 CoreFoundation/CFByteOrder.h에 정의되어 있으며 Byte-Order Utilities Reference에 기술되어 있습니다. Byte-Order Utilities Reference의 위치는 ADC Home > Reference Library > Documentation > Core Foundation > Core Foundation Reference > Byte-Order Utilities Reference 입니다. 이 함수들에 대한 자세한 사항은 Memory Management의 Byte Swapping 아티클을 읽어보시기 바랍니다. Memory Management 문서의 위치는 ADC Home > Reference Library > Documentation > Core Foundation > Resource Management > Memory Management 입니다.
  • 파운데이션 바이트 오더 함수는 헤더파일 Foundation/NSByteOrder.h 에 정의되어 있으며Foundation Reference for Objective-C에 기술되어 있습니다. Foundation Reference for Objective-C의 위치는 ADC Home > Reference Library > Documentation > Cocoa > Objective-C Language > Foundation Reference for Objective-C 입니다.
  • 코어 엔디안 API는 헤더파일 CarbonCore/Endian.h 에 정의되어 있으며 Core Endian Reference에 기술되어 있습니다. Core Endian Reference의 위치는 ADC Home > Reference Library > Documentation > Carbon > Data Management > Core Endian Reference 입니다.
참고 : 바이트 스왑 루틴을 사용할 때, 컴파일러는 코드를 최적화하므로 코드가 실행되는 아키텍쳐에 필요한 경우에 한해 루틴이 실행됩니다.


[편집] 효과적인 바이트 스왑 (Byte Swapping Strategies )

효과적인 스왑 바이트는 데이터의 포맷에 달려있습니다. universal routine이라는 것은 없으며 모든 바이트 오더 차이점에 유의해야 합니다. 모든 프로그램은 데이터를 스왑해야 하거나 데이터 타입, 소스 데이터 엔디안 순서, 호스트 엔디안 순서에 대해 알고 있어야 합니다.

상수

컴파일된 실행파일의 일부분인 상수는 호스트 바이트 순서입니다. 네이티브하게 지속되지 않는 데이터의 부분에 있는 상수에 대해서만 바이트를 스왑해야 하며, 또는 상수가 호스트 사이를 이동하는 경우에도 바이트를 스왑해야 합니다. 앞서 대부분의 경우 보다 빠르게 또는 shift를 사용하는 수학 연산이 필요한 프로세서 성능, 또는 다른 간단한 작업시에 바이트를 스왑할 수 있습니다.

만약 메모리에서 특정 엔디안 포맷의 데이터를 사용해야 하는 정의되고 계산된 구조라면, OSSwapConst 매크로와 libkern/OSByteOrder.h에 정의된 OSSwap Const 변수를 사용합니다. 이러한 매크로는 high-level 어플리케이션에서 사용될 수 있습니다.

Custom Apple Event Data

어떤 Apple event는 Apple Event Interprocess Messaging Protocol을 따르는 high-level 이벤트입니다. Apple Event Manager는 같은 컴퓨터에 있는 어플리케이션간에 또는 리모트 컴퓨터상에 있는 어플리케이션 사이에 Apple event를 전송합니다. 개발자는 고유한 Apple event 데이터 타입을 정의할 수 있으며, Apple Event Manager API를 사용해 Apple event를 보내거나 받을 수 있습니다.

Mac OS X은 시스템에 정의된 Apple event 데이터 타입을 관리하며, 현재 실행 코드에 대해 핸들링합니다. 개발자는 특별한 태스크에 대해 관여할 필요가 없습니다. 어플리케이션이 Apple event로부터 추출한 데이터는 시스템에 정의되어 있으며, 어플리케이션의 프로세스에 대해 이벤트가 주어지기 전에, 시스템은 개발자를 위해 데이터를 스왑합니다. 당신은 Apple event로부터 시스템에 정의된 데이터 타입을 네이티브 엔디안처럼 다룰 수 있도록 원할 것입니다. 비슷하게, 만약 당신이 보낸 Apple event에 네이티브 엔디안 데이터 타입을 넣는다면, 그리고 그것이 시스템에 정의된 데이터 타입이라면, 리시버는 고유의 네이티브 엔디안 포맷으로 데이터를 변환할 수 있습니다.

하지만 당신이 정의한 커스텀 Apple event 데이터 타입에 대한 바이트 오더의 차이점을 설명해야 합니다. 아래중 한가지 방법으로 수행할 수 있습니다.

  • (flipper로 알려진) 바이트 스왑 콜백 루틴을 기록하고 시스템을 지원합니다. 시스템이 당신의 Apple event 데이터를 스왑하고 당신의 flipper가 데이터가 정확한 엔디안 포맷에 데이터를 얻습니다. 더 자세한 내용은 “Writing and Installing a Callback to Swap Data Bytes”을 참고하십시오.
  • 사용하기 위해 선택된 하나의 엔디안 포맷은 아키텍쳐에 따릅니다. 그리고 나서 커스텀 Apple event 데이터를 읽거나 쓸때, Core Foundation Byte Order Utilities function인 CFSwapInt16BigToHost 와 CFSwapInt16HostToBig인 big-to-host 와 host-to-big routine을 사용합니다.

커스텀 리소스 데이터

Mac OS X에서는 리소스를 사용하기 위해 미리 준비된 방법으로 어플리케이션 번들안에 파일( 이미지 파일, 사운드, 로컬라이즈된 텍스트, 아카이브된 유저 인터페이스 파일등의 리소스)을 지원합니다. 이번 절에서 이야기하는 리소스 데이터 타입은 카본에서 Resource Manager-style file로 정의되어 있습니다. 리소스 매니저는 Mac OS X 전에 만들어 졌습니다. 만약 어플리케이션이 리소스 매니저 형태의 리소스 파일을 사용하다면, 어플리케이션 번들에서 Mac OS X 형태의 리소스를 사용하는 것을 생각해 보기 바랍니다.

일반적으로 리소스는 메뉴, 윈도우, 컨트롤, 다이얼로그, 사운드, 아이콘과 같은 데이터를 포함합니다. 비록 시스템이 여러 표준 리소스 타입 (특정 퀵타임 무비에 사용되는 'moov', 메뉴를 정의하기 위해 사용하는 'MENU'와 같이) 을 정의하고 있다고 하더라도, 어플리케이션에 사용하는 고유한 private resource type을 만들 수 있습니다. 리소스 데이터 타입을 정의하기 위해 리소스 매니저 API를 사용하고, 리소스 데이터를 얻거나 설정할 수 있습니다.

Mac OS X은 메모리에 트랙을 유지하며 어플리케이션이 리소스를 읽거나 쓸 수 있도록 합니다. 어플리케이션과 시스템 소프트웨어는 자체 리소스 타입을 따르는 리소스에 대해 데이터를 변환합니다. 일반적으로 OS가 리소스(어플리케이션 아이콘)를 읽도록 하지만, 리소스를 직접 읽거나 쓰기위해 리소스 매니저 함수를 호출할 수도 있습니다.

Mac OS X은 당신을 위해 시스템에 정의된 리소스를 관리하고, 현재 실행되는 코드에 대해 그것들을 직접 핸들링합니다. 만약 어플리케이션이 Intel 기반 Macintosh에서 실행된다면, Mac OS X은 바이트를 스왑하고 어플리케이션 아이콘, 메뉴나 다른 표준 리소스가 정확하게 표시되며, 디스크로부터 리소스 데이터를 읽거나 쓸때 아키텍쳐간의 바이트 오더 차이에 대해 책임을 져야 합니다.

커스텀 리소스 매니저 형태의 리소스 데이터를 다루기 위해 아래의 효과적인 방법을 사용할 수 있습니다. 커스텀 Apple event 데이터도 같은 방법을 사용해 효과적으로 핸들링할 수 있다는 것을 알려드립니다.

  • 시스템이 스왑되어야 하는 리소스를 결정할 때에는, 시스템에 대한 바이트 스왑 콜백 루틴을 지원합니다. 자세한 사항은 “Writing and Installing a Callback to Swap Data Bytes”을 보시기 바랍니다.
  • 항상 아키텍쳐를 따르는 같은 엔디안 포맷을 사용하여 데이터를 기록합니다. 그후, 커스텀 리소스 데이터를 읽거나 쓸 때, Core Foundation Byte Order Utilities function인 CFSwapInt16BigToHost 와 CFSwapInt16HostToBig와 같은 big-to-host 과 host-to-big routine을 사용합니다.
노트 : 만약 비트를 미리 읽어 리소스를 표시하는 오래된 코드를 수정한다면, 바이트 스왑해야 하는 모든 리소스에서 비트를 미리 읽는 것을 제거해야 합니다. Mac OS X에서는 항상 대부분 비트를 미리 읽는 것이 불필요합니다. 만약 비트를 미리 읽는 것을 제거할 수 없다면, 리소스를 읽은 후 리소스 데이터를 스왑해야 합니다. Mac OS X에서 비트를 미리 읽는 것은 어플리케이션 코드가 실행되기전 읽기위한 리소스가 원인이 되기 때문에, 자동적으로 바이트를 스왑하기 위한 flipper 콜백을 사용할 수 없습니다.

부동소수점 변수

코어 파운데이션은 함수의 집함과 부동소수점 변수에 사용에 도움을 줄 수 있는 두개의 특별한 데이터 타입을 정의하고 있습니다. 이러한 함수는 나중에 디코드 될 수 있도록 32- 와 64- 비트 부동소수점 변수로 인코드되어 있으며 가능한한 바이트를 스왑합니다. 목록 3-2sms 64-비트 부동소수점 수를 인코드하는 방법을 보여주며 목록 3-3은 이것을 디코드하는 방법을 보여줍니다.

목록 3-2 64-비트 부동소수점 수 인코딩

double d = 3.0;
CFSwappedFloat64 swappedDouble;
// Encode the floating-point value.
swappedDouble = CFConvertFloat64HostToSwapped(d);
// Call the appropriate routine to write swappedDouble to disk, 
// send it to another process, etc.
write(myFile, &swappedDouble, sizeof(swappedDouble));

데이터 타입 CFSwappedFloat32와 CFSwappedFloat64는 canonical하게 표현되는 부동소수점 값을 담고 있습니다. CFSwappedFloat 데이터 타입 자체는 부동소수점 변수가 아니므로 직접 사용할 수는 없습니다. 하지만 이것을 다른 프로세스에게 보낼 수 있으며, 디스크에 저장하거나 네트워크를 통해 보낼 수 있습니다. 포맷이 변환 함수로 정규 포맷으로 변환되거나 변환되어지기 때문에 명시적으로 스와핑이 필요없습니다. 가능한한 포맷 변환 동안은 바이트를 스왑합니다.

목록 3-2 64-비트 부동소수점 수 디코딩

float f;
CFSwappedFloat32 swappedFloat;
// Call the appropriate routine to read swappedFloat from disk, 
// receive it from another process, etc.
read(myFile, &swappedFloat, sizeof(swappedFloat));
f = CFConvertFloat32SwappedToHost(swappedFloat

NSByteOrder.h 헤더 파일은 여기에서 논의된 코어 파운데이션 함수와 동등한 함수를 정의합니다.

정수

OSReadLittleInt16과 OSWriteLittleInt16과 같은 system library byte-access function는 일반적인 바이트 스왑을 지원합니다. 만약 네이티브 포맷이 대상이 되는 엔디안 포맷과 다르다면, 이러한 함수는 바이트를 스왑합니다. libkern/OSByteOrder.h 헤더 파일에 정의되어 있습니다.

노트 : OSReadXXX 와 OSWriteXXX 함수는 OSSwapXXX 함수 또는 higher-level framework에 있는 다른 함수들보다 높은 퍼포먼스를 제공합니다.

코어 파운데이션은 바이트를 스왑하기 위한 세가지의 최적화된 primitive 함수를 지원합니다. - CFSwapInt16, CFSwapInt32, CFSwapInt64. 다른 스와핑 함수 모두는 작업을 완료하기 위해 이러한 primitive를 사용합니다. 일반적으로 이러한 primitive를 직접적으로 사용할 필요는 없습니다. primitive 스와핑 함수가 무조건 스왑할지라도, 스왑 바이트가 필요하지 않을때 그리고 소스와 호스트 바이트 오더가 같다면 higher-level 스와핑 함수가 아무것도 하지 않도록 정의되어 있습니다. 정수형에 대해, 이러한 함수는 CFSwapXXXBigToHost, CFSwapXXXLittleToHost, CFSwapXXXHostToBig, CFSwapXXXHostToLittle와 같은 형태를 가지고 있으며, XXX는 Int32와 같은 데이터 타입입니다. 예를 들어 리틀 엔디안 컴퓨터에서 네트워크 바이트 오더가 빅 엔디안인 네트워크로부터 16 비트 정수값을 읽기 위해 CFSwapInt16BigToHost 함수를 사용합니다. 목록 3-4는 이러한 과정을 보여줍니다.

목록 3-4 빅 엔디안에서 host-endian으로 16비트 정수를 스와핑

SInt16  bigEndian16;
SInt16  swapped16;
// Swap a 16-bit value read from the network.
swapped16 = CFSwapInt16BigToHost(bigEndian16);

데이터 스트럭쳐의 필드에 정수가 있다고 한다면, 목록 3-5는 바이트를 스왑하는 방법을 보여줍니다.

목록 3-5 리틀 엔디안에서 host-endian으로 정수를 스왑하는 경우

// Swap the bytes of the values if necessary.
aStruct.int1 = CFSwapInt32LittleToHost(aStruct.int1)
aStruct.int2 = CFSwapInt32LittleToHost(aStruct.int2)

가능한한 코드는 바이트를 스왑합니다. 만약 호스트가 빅 엔디안 아키텍쳐라면, 샘플 코드의 함수는

각 필드에 바이트를 스왑합니다. 리틀 엔디안 컴퓨터에서 실행될 때 코드는 아무런 동작을 하지 않고 컴파일러는 코드를 무시합니다.

IP 어드레스와 다른 "False" 숫자 값

만약 레지스터에 4바이트 크기를 저장하기 위한 편리하고 유용한 방법과 같이 int 또는 long 데이터 값을 사용하는 코드가 있다면, 크기가 중요하게 의미있는 정수가 아니라고 할지라도, 데이터의 바이트를 스왑하지 마십시오. 대부분의 일반적인 예(실례로 IPv4 어드레스와 같은)는 정수의 의미가 중요하지 않은 4바이트 용량입니다. IP 어드레스로 표현되는 숫자는 산술연산의 형태가 아닙니다. 호스트의 개념과 네트워크 바이트 순서와 같은 것은 적용되지 않습니다. IP 어드레스에 대한 순서는 기록된 순서일 뿐입니다. 예를 들어, 아키텍쳐를 따르지 않는 IP 어드레스 17.1.2.3 의 17은 메모리의 첫번째이며 3은 메모리의 마지막입니다.

네트워크 관련 데이터

네트워크 관련 데이터는 일반적으로 빅 엔디안 포맷(network byte order로 알려져 있습니다.)을 사용하며, 네트워크 사이나 Intel 기반 Macintosh간의 통신시에 바이트를 스왑할 필요가 없습니다. 아마도 이미 사용하고 있는 데이터 폼 송,수신용 PowerPC 코드를 수정할 필요는 없을겁니다. Intel 기반 Macintosh 컴퓨터에서라면 네트워크 관련 코드와 고유의 바이트 순서를 사용하여 네트워크로 데이터를 전송하는 코드는 자세하게 살펴 보셔야 합니다. 네트워크를 통해 받는 특이한 데이터라면 역시 핸들링이 필요하며, 호스트 마이크로프로세서에서 사용하는 고유한 엔디안 포맷에 대해 값의 바이트를 스왑합니다.

네트워크 바이트 오더와 호스트 바이트 오더간의 변환에 대해 아래의 나열된 POSIX 함수를 사용할 수 있습니다. (다른 바이트 스왑 함수도 네트워크 데이터를 핸들링하는데 유용합니다. 이러한 함수들은 OSByteOrder.h 와 CFByteOrder.h 헤더파일에 정의되어 있습니다.)

  • 네트워크 에서 호스트로
    • uint32_t ntohl (uint32_t netlong);
    • uint16_t ntohs (uint16_t netshort);
  • 호스트에서 네트워크로
    • uint32_t htonl (uint32_t hostlong);
    • uint16_t htons (uint16_t hostshort);

이러한 함수들은 man 페이지에 기술되어 있으며 터미널 또는 Xcode를 통해 보실 수 있습니다.

sockaddr_in 스트럭쳐의 sin_saddr, s_addr, sin_port 필드는 항상 네트워크 바이트 오더를 사용해야 합니다. man 페이지를 살펴보시면 모든 BSD 네트워킹 함수에 대해 아규먼트의 고유한 엔디안 포맷을 찾을 수 있습니다.

OSType 에서 스트링으로 변환

CFString (CFStringRef 데이터 타입) 객체로(또는 객체로부터) OSType 데이터 타입을 변환하기 위해서는 UTCreateStringForOSType 와 UTGetOSTypeFromString을 사용할 수 있습니다. 이 함수는 Uniform Type Identifiers Overview에 기술되어 있고, Launch Services framework의 한 부분인 UTType.h 헤더 파일에 정의되어 있습니다. Uniform Type Identifiers Overview의 위치는 ADC Home > Reference Library > Documentation > Carbon > Data Management > Uniform Type Identifiers Overview 입니다.

4글자의 리터럴을 사용할때 “abcd” != 'abcd' 라는 것을 잊지 마십시오. 차라리 'abcd' == 0x61626364 라는 형태로 기억하시기 바랍니다. 'abcd’는 문자열 데이터가 아닌 정수 데이터 처럼 다뤄지며, 'abcd’ 32비트 정수형입니다. (FourCharCode 데이터 타입은 UInt32 데이터 타입입니다.) 컴파일러는 이러한 것을 스왑하지 않습니다. 만약 보이지 않는 캐릭터를 다뤄야할 필요가 있다면 쉬프트 연산은 사용할 수 있습니다.

예를 들어, 표준 C printf-style semantic를 사용해 OSType 또는 FourCharCode 타입을 출력한다면,

printf("%c%c%c%c", (char) (val >> 24), (char) (val  >> 16), 
                    (char) (val >> 8), (char) val)

사용하거나 대신 아래처럼 사용할 수도 있습니다.

printf("%4.4s", (const char*) &val)

유니코드 텍스트 파일 Mac OS X은 유니코드를 인코드할 경우 종종 UTF-16을 사용합니다. (UniChar 데이터 타입은 double-byte value 입니다.) 어떤 멀티바이트 데이터와 같이 유니코드 캐릭터는 마이크로프로세서에서 사용되는 byte ordering method 와 같이 민감합니다. 파일의 시작에 표시된 byte order mark (BOM)는 프로그램이 읽을때 데이터를 쓸 때 사용한 byte ordering method가 어떤 것인지를 알려줍니다. 유니코드 표준은 유니코드 데이터 파일에 byte order mark가 없는 데이터는 빅 엔디안처럼 다루도록 설명하고 있습니다. 물론 BOM이 모든 것을 대신하는 것은 아니지만, 어떤 아키텍쳐가 다른 아키텍쳐로부터 파일을 읽을 경우 확실한 방법을 알려줍니다.

표 3-1은 UTF-8, UTF-16, UTF-32에 대한 표준 byte order mark 입니다. (UTF-8 BOM은 엔디안 이슈에 사용되지 않지만, 파일이 UTF-8이라는 것을 알려주는데 태그가 사용됩니다.)

표 3-1 Byte order marks

Byte order mark Encoding form
EF BB BF UTF-8
FF FE UTF-16/UCS-2, little endian
FE FF UTF-16/UCS-2, big endian
FF FE 00 00 UTF-32/UCS-4, little endian
00 00 FE FF UTF-32/UCS-4, big endian

파일을 읽을 때 아래의 스텝을 따른다면, 어플리케이션에서 파일을 읽을 때 byte order mark를 확인할 필요도 없을 뿐만아니라 long 처럼 바이트를 스왑할 필요도 없습니다.

  1. 파일 (또는 문자열)의 컨텐츠에 대한 포인터를 얻을 수 있는 mmap 파일을 구성합니다. 메모리에 있는 파일을 읽을 경우 가장 빠른 방법이며 다음 스텝으로 가기 위한 준비 작업입니다.
  2. 함수 CFStringCreateWithBytes에서 isExternalRepresentation 파라미터는 true로 설정하고 호출하거나 함수 CFStringCreateWithExternalRepresentation을 호출하여 CFString 객체를 생성합니다. kCFStringEncodingUnicode (UTF-16 용) 이나 kCFStringEncodingUTF8 (UTF-8 용)을 사용합니다. 두 가지의 함수는 필요한 경우 BOM swaps byte를 해석합니다. BOM은 메모리에 사용되지 않으며, 데이터 전송에 대해 단독으로 사용합니다. (파일, 클립보드와 같은 곳에서)

요약하면, 유니코드 파일에 관심을 가지고 아래의 안내를 따르면 어플리케이션이 최고의 성능으로실행됩니다.

  • 응용프로그램 바깥에서 UTF-16과 UTF-8로인코딩된 파일을 다룰 때는 BOM을 사용합니다.
  • 내부적으로 네이티브 엔디안 UniChar 데이터 타입을 사용합니다.
  • 파일로 UTF-16을 쓸때는 BOM을 생성합니다. 이상적으로는 리틀 엔디안 포맷을 사용하는 아키텍쳐에 대해서만 BOM을 생성해야 합니다만, 빅 엔디안을 포맷을 사용하는 아키텍쳐에도 BOM을 생성해야 합니다.
  • 클립보드에 데이터를 넣을 때, 'utxt' 데이터는 BOM을 가지고 있지 않습니다. 단지 'ut16' 데이터가 BOM을 가져야 합니다. 만약 Cocoa에서 NSString을 pasteboard에 넣는다면, BOM에 대해 신경쓰지 않아도 됩니다.

더 많은 정보는 유니코드 웹사이트에서 "UTF & BOM"과 관련된 정보를 보시기 바랍니다.

http://www.unicode.org/faq/utf_bom.html

Apple Event Manager는 데이터의 고유 타입을 사용할 수 있는 텍스트 상수를 지원합니다. Mac OS X v10.4의 경우는 두가지의 텍스트 상수만을 권장합니다.

  • typeUTF16ExternalRepresentation, byte order mark (BOM) 옵션을 이용해 16비트 외부 표현에서 고유 유니코드 텍스트로 나타낼 수 있습니다. 이 상수 표현은 BOM 또는 데이터가 UTF-16 빅 엔디안 포맷이라는 것을 보장합니다.
  • typeUTF8Text는 8비트 유니코드 (UTF-8 인코딩)을 표현합니다.

상수 typeUnicodeText는 네이티브 바이트 순서 포맷에서 BOM 옵션을 이용해 utxt 텍스트 데이터를 표시합니다. 이 상수는 명시적으로 유니코드 인코딩 또는 바이트 오더 정의를 나타내지는 않습니다.

Scrap Manager는 flavor 타입 상수인 kScrapFlavorTypeUTF16External을 지원하며, 이것은 byte order mark (BOM)옵션을 사용해 유니코드 텍스트 16비트 외부 표현을 나타냅니다.

Values in an Array

목록 3-6의 루틴은 배열안의 값을 바이트 스왑을 위해 사용할 수 있는 접근을 보여줍니다.

목록 3-6 배열안의 값의 바이트를 스왑하는 루틴

inline static void
 SwapUInt32Array (uint32_t *p, size_t count)
 {
    uint32_t *end = (uint32_t *)((uintptr_t)p + count * sizeof(*p));
    do  {
        *p = OSReadSwapInt32(p, 0);
    } while (++p < end)
}

[편집] 바이트 스왑 데이터에 대한 콜백의 기록과 설치

flipper와 같은 것을 사용해 시스템에 대한 custom resource data, custom pasteboard data, custom Apple event data를 위한 바이트 스왑 콜백 루틴을 지원할 수 있습니다. 바이트 스왑 콜백이 설치될 때, 도메인이 어떤 데이터 타입을 따를 지 지정해야 합니다. 여기는 Apple event 와 resource의 두가지 데이터 도메인이 있습니다. 리소스 데이터 도메인은 custom pasteboard data 또는 custom resource data를 지정합니다. 만약 콜백이 Apple event 와 resource 두 가지 모두를 지원할 수 있다면, 가장 좋은 방법입니다.

코어 엔디안 API는 custom resource와 Apple event data의 바이트 스왑을 지원하기 위한 콜백을 정의합니다. 바이트 스왑을 원하는 데이터의 각 타입을 위한 한개의 콜백은 지원해야 합니다. CoreEndianFlipProc 콜백의 프로토타입은 아래와 같습니다.

typedef CALLBACK_API (OSStatus, CoreEndianFlipProc)
    (OSType dataDomain, 
    OSType dataType, 
    short id, 
    void *dataPtr, 
    UInt32 dataSize, 
    Boolean currentlyNative, 
    void *refcon
);

콜백은 아래의 파라미터를 사용합니다.

  • dataDomain—flipper callback이 적용된 도메인을 지정하는 OSType 값입니다. kCoreEndianResourceManagerDomain 값은 도메인이 resource, pasteboard data라는 것을 표시합니다. kCoreEndianAppleEventManagerDomain 은 도메인이 Apple event data라는 것을 표시합니다.
  • dataType—바이트 스왑을 위해 콜백이 필요한 데이터 타입입니다. 이것은 resource 타입, pasteboard 타입, Apple event의 4 캐릭터코드 입니다.
  • id—데이터 타입의 리소스 id입니다. 만약 dataDomain 파라미터가 kCoreEndianResourceManagerDomain 가 아니라면 이 필드가 무시됩니다.
  • dataPtr—입력시, flip되는 데이터를 가리킵니다. 출력시에는 스왑되는 데이터를 가리킵니다.
  • dataSize—dataPtr 파라미터 변수가 가리키고 있는 데이터의 크기입니다.
  • currentlyNative—바이트 스왑의 방향을 나타나는 BOOL 값입니다. 값이 true라면 dataPtr 파라미터가 가리키고 있는 데이터의 현재 실행되는 코드의 바이트 순서를 표시합니다. PowerPC Macintosh에서 true값은 데이터가 빅 엔디안 포맷이라는 것을 알려줍니다. Intel 기반 Macintosh에서 true 값은 데이터가 리틀 엔디안 포맷이라는 것을 알려줍니다.
  • refcon—콜백이 필요한 데이터를 담거나 참조하는 32비트 값입니다.

콜백은 바이트 스왑이 성공적인 경우에도 결과코드를 리턴합니다. 만약 바이트 스왑된 데이터가 error와 에러 상태(errCoreEndianDataTooShortForFormat, errCoreEndianDataTooLongForFormat, errCoreEndianDataDoesNotMatchFormat)를 표시하기 위한 특정 결과 코드가 없다면, 콜백은 noErr을 리턴해야 합니다. 결과 코드는 caller에게 고유 매니저(Resource Manager (ResError) 또는 Apple Event Manager)를 통해 전달됩니다.

숫자가 아닌 것(스트링, 바이트 스트림과 같은 것들...)에 대해서는 바이트를 스왑할 필요가 없습니다. word의 바이트 순서 또는 long word가 중요한 데이터 타입의 바이트 스왑이 콜백이 지원하도록 해야 합니다. (유니코드를 위해 준비된 방법은 이 문서의 "유니코드 텍스트 파일"을 참고하십시오.)

콜백은 데이터와 스왑된 바이트의 데이터 스트럭쳐를 자세하게 확인하고 있어야 합니다. :

  • 모든 카운트와 길이이며 배열 인덱스는 고유 값과 관련되어 있습니다.
  • 모든 integer와 long이며 호환되는 타입의 변수로 읽어들일때, 변수에서 정확하게 다룰 수 있습니다. (numerical, offset, shift operations 와 같이)

콜백을 사용하는 작업에 코어 엔디안 API는 이러한 함수를 지원합니다.

  • CoreEndianInstallFlipper는 특정 데이터 타입(custom resource 또는 custom Apple Event) 에 대해 콜백을 설치합니다. 어플리케이션에 정의된 리소스 데이터 타입을 위한 바이트 스왑 콜백을 설치한 후, 항상 리소스 타입의 작업에 Resource Manager 함수를 호출할 수 있으며, 만약 콜백에 해당하는 작업이 있다면 시스템은 콜백을 호출합니다. (콜백이 pasteboard 데이터에 대해 작용한다면, 시스템도 고유 시간에 콜백으로 작동합니다.) 비슷하게 만약 콜백에 대한 도메인처럼 Apple event를 지정하면, 항상 데이터 타입에 대한 작업에 Apple Event Manager 함수를 부를 수 있으며, 콜백은 그에 해당하는 작업을 수행합니다.
  • CoreEndianGetFlipper는 특정 데이터 타입을 위해 설치된 콜백을 포함합니다. flipper가 주어진 데이터 타입이 가능한지 아닌지 결정된 이 함수를 호출할 수 있습니다.
  • CoreEndianFlipData는 특정 데이터 타입과 연관된 콜백을 실행합니다. 시스템이 필요한 경우 당신의 콜백을 호출하므로 이 함수가 필요하지는 않습니다.

예를 든 것처럼, 목록 3-7에 정의된 custom resource type ('PREF')에 대한 콜백을 볼 수 있습니다. MyPreferences 스트럭쳐는 디스크에 preferences 데이터를 저장합니다. 스트럭쳐는 값의 수를 담고 있으며 RGBColor 데이터 타입과 RGBColor 값의 배열의 두 가지 인스턴스를 포함하고 있습니다.

목록 3-7 커스텀 리소스 선언

#define kMyPreferencesType      'PREF'
 
struct MyPreferences {
                SInt32          fPrefsVersion;
 
                Boolean         fHighlightLinks;
                Boolean         fUnderlineLinks;
 
                RGBColor        fHighlightColor;
                RGBColor        fUnderlineColor;
                SInt16          fZoomValue;
 
                char            fCString[32];
 
                SInt16          fCount;
                RGBColor        fPalette[];
};

RGBColor 데이터 스트럭쳐에 스왑된 바이트의 함수가 기록하는 데이터 타입인 RGBColor를 핸들링할 수 있습니다. 이러한 함수에는 목록 3-8의 MyRGBSwap과 같은 함수가 있습니다. 이 함수는 RGBColor 데이터 스트럭쳐안의 각 값을 바이트 스왑하기 위해 코어 엔디안 매크로인 EndianS16_Swap를 호출합니다. 함수가 RGBColor 데이터 타입의 값은 그 자신의 바이트를 스왑해야할 필요가 없다면 함수가 호출될 필요가 없기때문에, 함수는 현재 실행되고 있는 시스템을 체크할 필요는 없습니다. MyRGBSwap 함수는 byte-swapping 콜백 루틴에 의해 호출되며, (목록 3-9에서 확인할 수 있습니다.) 커스텀 'PREF' 리소스를 핸들링하기 위해 지원합니다. (목록 3-7에 있습니다.)

목록 3-8 RGBColor 데이터를 위한 flipper 함수

static void MyRGBSwap (RGBColor *p)
{
    p->red = Endian16_Swap(p->red);
    p->blue = Endian16_Swap(p->blue);
    p->green = Endian16_Swap(p->green);
}

목록 3-9는 커스텀 'PREF' 리소스에 대한 바이트 스왑 콜백을 보여줍니다. 열마다 표시된 숫자에 대한 설명은 아래쪽에 있습니다. flipper는 잘못 만들어지거나 예상할 수 없는 길이의 데이터를 체크합니다. 만약 flipper 루틴을 통과한 데이터가 일반적인 flip된 타입 보다 짧은 길이거나 (예를 들어 ) 배열 카운트 대신 쓰레기 값을 담고 있다면, flipper가 데이터의 끝에서 데이터를 읽거나 쓰지 않도록 주의해야 합니다. 대신 루틴은 에러를 리턴합니다.

목록 3-9 커스텀 'PREF' 리소스에 대한 flipper

#define kCurrentVersion    0x00010400
 
static OSStatus MyFlipPreferences (OSType dataDomain, // 1
                    OSType dataType,  // 2
                    short id,  // 3
                    void * dataPtr,  // 4
                    UInt32 dataSize,  // 5
                    Boolean currentlyNative, // 6
                    void* refcon) // 7
{
    UInt32  versionNumber;
 
    OSStatus status = noErr;
    MyPreferences* toFlip = (MyPreferences*) dataPtr;      // 8
    int count, i;
 
    if (dataSize < sizeof(MyPreferences))
        return errCoreEndianDataTooShortForFormat; // 9
    if (currentlyNative)  // 10
    { 
        count = toFlip->fCount;
        versionNumber = toFlip->fPrefsVersion;
        toFlip->fPrefsVersion = Endian32_Swap (toFlip->fPrefsVersion); 
        toFlip->fCount = Endian16_Swap (toFlip->fCount);
        toFlip->fZoomValue = Endian16_Swap (toFlip->fZoomValue);
    }   
    else  // 11
    {
        toFlip->fPrefsVersion = Endian32_Swap (toFlip->fPrefsVersion);
        versionNumber = toFlip->fPrefsVersion;
        toFlip->fCount = Endian16_Swap (toFlip->fCount);
        toFlip->fZoomValue = Endian16_Swap (toFlip->fZoomValue);
        count = toFlip->fCount; 
    }
    if (versionNumber != kCurrentVersion) // 12
                return errCoreEndianDataDoesNotMatchFormat;
 
    MyRGBSwap (&toFlip->fHighlightColor); // 13
    MyRGBSwap (&toFlip->fUnderlineColor); // 14
 
    if (dataSize < sizeof(MyPreferences) + count * sizeof(RGBColor))
        return errCoreEndianDataTooShortForFormat;  // 15
 
    for(i = 0; i < count; i++) 
    {   
        MyRGBSwap (&toFlip->fPalette[i]); // 16
    }
 
    return status;    // 17
}

각열에 대한 설명은 아래와 같습니다.

  1. 시스템은 어떤 콜백이 적용된 도메인을 당신의 콜백에 패스합니다. 당신은 CoreEndianInstallFlipper 함수를 사용해서 콜백을 설치할 때, 도메인을 정의합니다.
  2. 시스템은 데이터를 위해 정의한 리소스 타입을 당신의 콜백에 패스합니다. 예를 들어 리소스 타입은 'PREF' 입니다.
  3. 시스템은 데이터 타임의 리소스 ID를 당신의 콜백에 패스합니다. 만약 데이터가 리소스가 아니라면, 값은 0입니다.
  4. 시스템은 바이트 스왑이 필요한 리소스 데이터에 대한 포인터를 당신의 콜백에 패스합니다. 이러한 경우 포인터는 MyPreferences 데이터 스트럭쳐를 참조합니다.
  5. 시스템은 이전 스텝에 기술된 포인터가 가리키고 있는 데이터의 크기를 당신의 콜백에 패스합니다.
  6. 시스템은 콜백에 패스되는 버퍼안의 데이터가 현재 실행되는 코드의 바이트 순서라면 true를 당신의 콜백에게 패스합니다. PowerPC Macintohs에서 currentlyNative가 ture이면 데이터는 빅 엔디안 순서입ˆ•. Inter 기반 Macintosh에서 currentlyNative가 true이면 데이터는 리틀 엔디안 순서입니다. 만약 당신의 콜백이 버퍼에 다른 데이터를 처리하기 위한 방법을 결정하기 위한 데이터 버퍼의 값을 사용한다면 (예를 들어, count 변수는 코드에 보입니다.), 그 값을 콜백이 사용하기 전에 flip을 해야할지를 당신은 알고 있어야 하기 때문에 당신의 콜백은 이 값을 알고 있어야 합니다.
  7. 시스템은 어플리케이션 고유 데이터를 참조하는 포인터를 당신의 콜백에 패스합니다. 예를 들어 콜백은 어떠한 어플리케이션 고유 데이터를 필요로 하지 않습니다.
  8. MyPreferences 데이터 타입에 대한 변수를 정의하고 새롭게 정의한 toFlip 변수에 대한 데이터 포인터의 컨텐츠를 할당합니다.
  9. 스트럭쳐의 고정된 길이의 포션을 체크합니다. 만약 적정 크기보다 작을 경우, 루틴은 errCoreEndianDataTooLongForFormat 에러를 리턴합니다.
  10. 만약 currentlyNative가 true라면 지역 변수에 대한 count 변수를 저장하고 나서 MyPreferences 데이터 스트럭쳐안의 다른 변수에 대한 바이트를 스왑합니다. 함수안에서 계속 반복해서 사용되기 때문에, count 변수는 스왑하기 전 저장해야 합니다. 만약 현재 실행되는 코드 안에 있다면 결과적으로 currentlyNative가 true라는 것은 값이 바이트 스왑될 필요가 없다는 것을 표시합니다. 하지만 값은 디스크에 저장되기 위해 스왑이 필요합니다. 값은 고유의 코어 엔디안 매크로를 사용하여 스왑합니다.
  11. 만약 currentlyNative가 false라면, 지역 변수에 대한 count 값을 저장하기 전에 MyPreferences 데이터 스트럭쳐 안의 값을 flip합니다. 결과적으로 currentlyNative가 fale라는 것은 콜백에서 사용될 수 있기전 count 값이 바이트 스왑을 가져야 한다는 것을 표시합니다.
  12. 데이터의 버전이 어플리케이션에서 지원될 수 있는지 체크합니다. 만약 지원되지 않는 버전이라면, 당신의 콜백은 데이터의 바이트를 스왑하지 않으며 errCoreEndianDataDoesNotMatchFormat
결과를 리턴합니다.
  1. 데이터 스트럭쳐의 fHighlightColor 필드의 바이트를 스왑하기 위해 MyRGBSwap 함수 (3-8에서 기술한)를 호출합니다.
  2. 데이터 스트럭쳐의 fUnderlineColor 필드의 바이트를 스왑하기 위해 MyRGBSwap 함수를 호출합니다.
  3. 적정 크기보다 작은지 데이터의 사이즈를 체크합니다. 아니라면, 루틴은 errCoreEndianDataTooLongForFormat 에러를 리턴합니다.
  4. fPalette 배열에서 엘레먼트들이 반복되며, 배열안에 있는 데이터의 바이트를 스왑하기 위한 MyRGBSwap 함수를 호출합니다.
  5. 데이터가 아무 에러 없이 flip 되었다는 것을 표시하기 위해 noErr를 리턴합니다.

플이 일부 에러를 체크하고 있지만, 가능한 모든 에러를 핸들링하는 코드를 담고 있지는 않습니다. flipper를 작성할 때는 코드에 이러한 코드를 넣어야 합니다.

노트 : 콜백은 MyPreferences 데이터 스트럭쳐 안의 어떤 BOOL 값도 flip 하지 않습니다. (이유는 한글자짜리 값이기 때문입니다.) 또한 콜백은 C String을 무시합니다.

함수 CoreEndianInstallFlipper를 호출하기 위해 바이트 스와핑 콜백 루틴을 설치합니다. 어플리케이션이 자신의 초기화 루틴을 호출하거나 또는 당신의 리소스를 열때 콜백을 설치해야 합니다. 예를들어 아래의 코드를 사용하여 목록 3-9에 보여진 flipper 콜백을 설치합니다.

OSStatus status = noErr;
status = CoreEndianInstallFlipper (kCoreEndianResourceManagerDomain,
                        kMyPreferencesType, 
                        MyFlipPreferences, 
                        NULL);

시스템은 리소스가 load되고 true이며 동시에 리소스가 기록된 상태에서 currentlyNative가 false일 때 특정 리소스 타입과 데이터 도메인에 대한 콜백을 실행합니다. 예를들어 샘플의 바이트 스왑 콜백은 어플리케이션에서 코드가 실행되는 아래의 라인을 실행합니다.

MyPreferences** hPrefs = (MyPreferences**) GetResource ('PREF',  128);

데이터의 바이트를 스왑하고 난 후, 원하는 만큼 수정할 수 있습니다.

Resource Manager가 디스크로부터 리소스를 읽을 때, 바이트 스왑 루틴 테이블안의 리소스 타입을 검색합니다. (예를 들어 'PREF') 만약 이러한 리소스 타입에 대한 콜백이 설치되어 있다면 Resource Manager는 콜백을 실행합니다. Resource Manager가 디스크에 리소스를 기록할 경우도 비슷한 액션이 취해 집니다. 고유한 루틴을 찾고 빅 엔디안 바이트 순서에 대한 리소스의 바이트를 스왑하기 위해 콜백을 실행합니다.

pasteboard 데이터에 대해 콜백을 설치한 어플리케이션으로부터 커스텀 데이터를 복사하거나 드래그할 때, 시스템은 적당한 때에 당신의 콜백을 실행합니다. 만약 네이티브 어플리케이션으로 커스텀 데이터를 복사하거나 드래그하면 데이터 콜백은 실행되지 않습니다. 만약 네이티브가 아닌 어플리케이션으로 커스텀 데이터를 복사하거나 드래그하면, 시스템은 커스텀 데이터의 바이트를 스왑하기 위한 당신의 콜백을 실행합니다. 만약 네이티브가 아닌 어플리케이션으로부터 당신의 어플리케이션으로 커스텀 데이터를 붙이거나 drop하고, 콜백이 커스텀 데이터에 대해 존재한다면, 시스템은 붙이기 와 drop이 일어나는 동시에 콜백을 실행합니다.

다른 pasteboard API는 다른 타입의 고유한 것을 사용합니다. Scrap Manager 와 Drag Manager 는 OSType 데이터 타입을 사용합니다. Pasteboard Manager는 Uniform Type Identifiers (UTI)를 사용하고, NSPasteboard는 자신 고유 타입의 메카니즘을 사용합니다. 각 케이스 별로, (만약 그 타입에 대한 바이트 스와핑 콜백이 있다면) 타입은 시스템에 의해 찾기 위한 OSType 데이터 타입으로 변환됩니다.

Apple event data type은 네트워크를 통해 보낼때 일반적으로 네트워크 바이트 오더에 대해 스왑합니다. 당신이 설치한 콜백은 다른 머신으로 보내도록 정의한 커스텀 데이터 타입에 대해서만 또는 다른 머신이 당신의 어플리케이션으로 Apple event data를 전송하는 경우 호출되됩니다. 네트워크에서 Apple event 바이트 오더는 빅 엔디안입니다.

일반적이지 않은 케이스에서 당신의 바이트 스왑 콜백이 실행되면, 당신은 특정 데이터 타입과 도메인데 대한 콜백 함수를 호출하기 위해 함수 CoreEndiaFlipData 를 호출할 수 있습니다.

[편집] 참고 사항 (See Also)

ADC Reference Library에는 아래의 유용한 리소스가 있습니다.

  • Byte-Order Utilities Reference는 Core Foundation byte order utilities API를 설명합니다. Byte-Order Utilities Reference의 위치는 ADC Home > Reference Library > Documentation > Core Foundation > Core Foundation Reference > Byte-Order Utilities Reference 입니다.
  • Byte Swapping, (Core Foundation Memory Management에 있는), 정수를 스왑하는 방법과 부동소수점 변수에 대해 Core Foundation byte-order utilities 사용을 보여줍니다. Byte Swapping의 위치는 ADC Home > Reference Library > Documentation > Core Foundation > Resource Management > Memory Management 의 Byte Swapping입니다.
  • Resource Endian Flippers 는flipper 작성에 대해 논의합니다. Resource Endian Flippers의 위치는 http://developer.apple.com/quicktime/icefloe/dispatch025.html 입니다.
  • File-System Performance Guidelines 메모리의 유니코드 파일의 매핑에 대한 유용한 정보를 제공합니다. File-System Performance Guidelines의 위치는 Introduction to File-System Performance Guidelines입니다.

[편집] 특정 시나리오에 대한 가이드 라인 (Guidelines for Specific Scenarios)

이 장은 관련된 특정 기술 또는 API에 대한 시나리오별 목록입니다. 비록 이러한 많은 시나리오가 일반적이지는 않더라도, 개발에 도움이 될만한 내용이 있는 지 각 주제들을 살펴보는 것이 좋을 것 같습니다. 각 주제는 알파벳 순입니다.

내용 :

  • Aliases
  • Archived Bit Fields
  • Automator Scripts
  • Bit Shifting
  • Bit Test, Set, and Clear Functions: Carbon and POSIX
  • Dashboard Widgets
  • Deprecated Functions
  • Disk Partitions
  • Double-Precision Values: Bit-by-Bit Sensitivity
  • Finder Information and Low-Level File System Operations
  • FireWire Device Access
  • Font-Related Resources
  • GWorlds
  • Java Applications
  • Java I/O API (NIO)
  • Machine Location Data Structure
  • Metrowerks PowerPlant
  • Multithreading
  • Objective-C: Messages to nil
  • Objective-C Runtime: Low-Level Operations
  • Open Firmware
  • OpenGL
  • OSAtomic Functions
  • Pixel Data
  • Quartz Bitmap Data
  • QuickDraw Routines
  • QuickTime Components
  • QuickTime Metadata Functions
  • Runtime Code Generation
  • System-Specific Predefined Macros
  • USB Device Access
  • See Also

[편집] Aliases

앨리어스는 모든 시스템에서 빅 엔디안입니다. AliasHandle의 끝에 특별한 정보가 추가된 어플리케이션은 특별한 데이터가 항상 endian-neutral이거나 정의된 엔디안 타입이어야 합니다. 바람직한 방법은 빅 엔디안입니다.

AliasRecord 데이터 스트럭쳐는 Mac OS X v 10.4.1 SDK에서 어플리케이션 빌드시 알 수 없습니다. AliasRecord의 userType 필드에 접근하는 코드는 반드시 Alias Manager 함수인 GetAliasUserType, GetAliasUserTypeFromPtr, SetAliasUserType, SetAliasUserTypeFromPtr을 사용해야 합니다. AliasRecord의 aliasSize에 접근하는 코드는 반드시 함수 GetAliasSize 이나 GetAliasSizeFromPtr를 사용해야 합니다.

이러한 Alias Manger 함수는 Mac OS X v10.4 이상에서 사용할 수 있습니다. 더 많은 정보는 Alias Manager Reference를 보시기 바라며 문서의 위치는 ADC Home > Reference Library > Documentation > Carbon > F