메타데이터 API의 코딩 규칙

이 항목에서는 메타데이터 API에서 사용되는 코딩 규칙에 대해 설명합니다.

문자열 매개 변수 처리

메타데이터 API는 모든 문자열을 유니코드 형식으로 노출합니다. 디스크상에서 기호 이름의 형식은 실제로는 UTF-8이지만 이는 메타데이터 API 클라이언트에 표시되지 않습니다. 반환되는 모든 문자열은 다음 세 매개 변수의 조합입니다. 실제 매개 변수 이름은 다양합니다.

  • [in] ULONG cchString - null 종결 문자를 포함하여 문자열이 반환될 버퍼의 크기(바이트)입니다.

  • [out] LPCWSTR wzString - 문자열이 반환될 버퍼에 대한 포인터입니다.

  • [out] ULONG *pchString - 반환된 문자열(null 종결 문자 포함)의 크기에 대한 포인터입니다. 버퍼가 너무 작아 전체 문자열을 저장할 수 없으면 반환된 문자열이 잘리고 오류 표시가 반환되며 원하는 경우 클라이언트에서 버퍼를 다시 할당하고 작업을 다시 시도할 수 있습니다.

기호 이름

문자열 매개 변수의 기호 이름에는 다음 규칙이 적용됩니다.

  • 기호 이름에 해당하는 문자열 매개 변수는 항상 null로 끝나는 것으로 간주되고 [in] 길이 매개 변수는 필요하지 않습니다. 포함된 null 문자는 지원되지 않습니다.

  • 입력 매개 변수 매개 변수 문자열이 너무 커서 자르지 않고는 저장할 수 없으면 오류가 반환됩니다.

사용자 문자열

사용자 제공 문자열 매개 변수에는 다음 규칙이 적용됩니다.

  • 사용자 문자열에 null 문자를 포함할 수 있지만 null 종결자는 포함할 수 없습니다.

  • 길이는 cchString 매개 변수에서 제공해야 합니다. 버퍼의 크기는 저장할 문자열의 길이와 같아야 합니다.

기본값 저장

필드, 매개 변수 및 속성의 기본값으로 상수를 메타데이터에 저장할 수 있습니다. 상수를 지정하는 데는 다음 세 개의 매개 변수가 사용됩니다. 실제 매개 변수 이름은 다양합니다.

  • [in] DWORD dwCPlusTypeFlag - 기본값의 형식을 지정하는 CorElementType 열거형의 값입니다.

  • [in] void const *pValue - 실제 기본값에 대한 포인터입니다. 예를 들어 0x0000002A가 들어 있는 4바이트 DWORD에 대한 포인터는 10진수 42에 대한 DWORD 값을 메타데이터에 저장합니다. dwCPlusTypeFlag에 지정되는 기본값 형식은 기본 형식이나 문자열 형식으로 제한됩니다. dwCPlusTypeFlag가 ELEMENT_TYPE_CLASS인 경우 기본값은 null입니다.

  • [in] ULONG cchValue - pValue가 가리키는 바이트 시퀀스의 유니코드 문자 수입니다. 이 매개 변수는 dwCPlusTypeFlag에 지정된 형식이 ELEMENT_TYPE_STRING인 경우에만 필요합니다. 다른 모든 경우에는 형식에서 길이가 유추됩니다.

기본값은 초기화 코드나 정적으로 초기화된 데이터 영역에는 자동으로 삽입되지 않고 메타데이터에만 기록됩니다.

기본값을 지정하지 않도록 나타내려면 dwCPlusTypeFlag의 모든 비트를 설정합니다. 즉, 값을 -1로 설정합니다.

반환 매개 변수에 대한 Null 포인터

메타데이터 API에서는 최소한의 오류 검사만 수행하므로 다음과 같은 경우 반환 매개 변수에 null이 아닌 포인터가 필요합니다.

  • Define 메서드에서는 반환되는 토큰에 null이 아닌 포인터가 필요합니다. 이러한 메서드는 사용자가 정의하려고 한 항목을 만들고 해당 항목의 토큰을 반환합니다. 필요하지 않은 경우 토큰을 삭제할 수 있습니다.

  • Find 메서드는 항목을 찾은 경우 해당 항목에 대한 토큰을 항상 반환합니다.

  • Get 메서드에서는 값을 반환받을 필요가 없는 매개 변수에 null을 전달할 수 있습니다.

  • Set 메서드에서는 일반적으로 반환 값이 없습니다. 업데이트 값과 함께 업데이트할 항목의 토큰을 전달하면 이러한 메서드에서 업데이트를 수행합니다.

무시되는 매개 변수 값

메타데이터 API의 일부 메서드는 이전에 정의한 항목의 속성을 변경하는 데 사용할 수 있습니다. 다음 예제에서는 이전에 IMetaDataEmit::DefineField를 호출할 때 제공된 필드 속성을 IMetaDataEmit::SetFieldProps 메서드를 사용하여 변경합니다.

HRESULT SetFieldProps(mdFieldDef fd, DWORD dwFieldFlags,
        DWORD dwDefType, void const *pValue, ULONG cchValue)

dwFieldFlags만 변경하고 pValue는 변경하지 않으려는 경우나 이와 반대의 경우가 있을 수 있습니다. 이 경우 오류를 방지하려면 값을 변경하지 않을 경우에도 매개 변수 값을 전달해야 합니다. 그러나 값을 변경하지 않으려는 경우 해당 인수가 무시되도록 지정하는 특정 값을 전달할 수 있습니다. 메타데이터 API에서는 다음과 같은 규칙을 사용하여 메서드 인수를 무시하도록 지정합니다.

  • 매개 변수가 포인터 형식인 경우 null 포인터를 전달합니다.

  • 매개 변수가 값 형식(일반적으로 플래그 비트 마스트)인 경우 –1로 설정된 모든 비트 값을 전달합니다.

오류 반환

IMetaDataDispenserEx, IMetaDataEmitIMetaDataImport 인터페이스의 거의 모든 메서드는 HRESULT 값을 반환하여 해당 결과를 나타냅니다. 이 값은 작업에 성공하는 경우 S_OK이고, 호출에 실패한 경우 작업 실패 원인을 설명하는 다른 값을 반환합니다.

모든 메타데이터 API에서 일반적으로 호출자가 너무 작은 문자열 버퍼를 제공하여 결과를 저장할 수 없으면 API에서는 버퍼 크기에 들어갈 수 있는 만큼의 문자를 복사하지만 HRESULT 값으로는 S_OK 대신 CLDB_S_TRUNCATION을 반환합니다.

IMetadata 인터페이스의 호출자는 컴파일러나 도구입니다. 이러한 호출자는 항상 오류를 검색하기 위해 각 호출의 반환 상태를 검사합니다. 이러한 경우 오류 조건은 사용자(예: 응용 프로그램)가 아니라 직접 호출자(예: 컴파일러)와 관련된 문제를 반영합니다.

메모리 관리

일반 COM 기본값은 호출 수신자가 할당하는 메모리를 호출자가 해제하는 것입니다. 그러나 메타데이터 메서드는 다르게 작동합니다.

대부분의 메타데이터 메서드는 메모리 블록에 대한 [out] 포인터를 반환합니다. 해당 메모리는 모듈의 메타데이터 힙의 일부이고 CLR(공용 언어 런타임)에서 소유합니다. 즉 CLR의 메모리 내 메타데이터 저장소를 직접 가리키는 포인터를 전달받으므로 응용 프로그램에서 메모리를 해제할 필요가 없습니다.

제네릭 지원

.NET Framework 버전 2.0에서는 메타데이터 API가 제네릭("파라메트릭 다형성"이라고도 함)을 지원하도록 크게 확장되었습니다. 제네릭은 C++ 템플릿과 유사합니다. C#에서 제네릭 클래스를 정의하는 예제는 다음과 같습니다.

public class Dictionary<Key, Val> { . . . }

이 경우 Dictionary 클래스에는 Key와 Val이라는 두 개의 제네릭 매개 변수가 사용됩니다. 다음 예제와 같이 클래스가 인스턴스화될 때 사용자가 제네릭 매개 변수의 형식을 선택합니다.

Dictionary<string, int> NameToPhone = new Dictionary<string, int>();
Dictionary<int, string> PhoneToName = new Dictionary<int, string>();

참고 항목

개념

메타데이터 개요