다음을 통해 공유


MetadataBuilder 클래스

정의

MetadataBuilder 클래스는 성능이 뛰어난 방식으로 어셈블리에 대한 메타데이터를 씁니다. 컴파일러 및 기타 어셈블리 생성 도구에서 사용하도록 설계되었습니다.

public ref class MetadataBuilder sealed
public sealed class MetadataBuilder
type MetadataBuilder = class
Public NotInheritable Class MetadataBuilder
상속
MetadataBuilder

예제

이 예제에서는 를 사용하여 MetadataBuilder콘솔 애플리케이션 어셈블리를 내보내는 방법을 보여줍니다.

private static readonly Guid s_guid = new Guid("87D4DBE1-1143-4FAD-AAB3-1001F92068E6");
private static readonly BlobContentId s_contentId = new BlobContentId(s_guid, 0x04030201);

private static MethodDefinitionHandle EmitHelloWorld(MetadataBuilder metadata, BlobBuilder ilBuilder)
{
    // Create module and assembly for a console application.
    metadata.AddModule(
        0,
        metadata.GetOrAddString("ConsoleApplication.exe"),
        metadata.GetOrAddGuid(s_guid),
        default(GuidHandle),
        default(GuidHandle));

    metadata.AddAssembly(
        metadata.GetOrAddString("ConsoleApplication"),
        version: new Version(1, 0, 0, 0),
        culture: default(StringHandle),
        publicKey: default(BlobHandle),
        flags: 0,
        hashAlgorithm: AssemblyHashAlgorithm.None);

    // Create references to System.Object and System.Console types.
    AssemblyReferenceHandle mscorlibAssemblyRef = metadata.AddAssemblyReference(
        name: metadata.GetOrAddString("mscorlib"),
        version: new Version(4, 0, 0, 0),
        culture: default(StringHandle),
        publicKeyOrToken: metadata.GetOrAddBlob(
            new byte[] { 0xB7, 0x7A, 0x5C, 0x56, 0x19, 0x34, 0xE0, 0x89 }
            ),
        flags: default(AssemblyFlags),
        hashValue: default(BlobHandle));

    TypeReferenceHandle systemObjectTypeRef = metadata.AddTypeReference(
        mscorlibAssemblyRef,
        metadata.GetOrAddString("System"),
        metadata.GetOrAddString("Object"));

    TypeReferenceHandle systemConsoleTypeRefHandle = metadata.AddTypeReference(
        mscorlibAssemblyRef,
        metadata.GetOrAddString("System"),
        metadata.GetOrAddString("Console"));

    // Get reference to Console.WriteLine(string) method.
    var consoleWriteLineSignature = new BlobBuilder();

    new BlobEncoder(consoleWriteLineSignature).
        MethodSignature().
        Parameters(1,
            returnType => returnType.Void(),
            parameters => parameters.AddParameter().Type().String());

    MemberReferenceHandle consoleWriteLineMemberRef = metadata.AddMemberReference(
        systemConsoleTypeRefHandle,
        metadata.GetOrAddString("WriteLine"),
        metadata.GetOrAddBlob(consoleWriteLineSignature));

    // Get reference to Object's constructor.
    var parameterlessCtorSignature = new BlobBuilder();

    new BlobEncoder(parameterlessCtorSignature).
        MethodSignature(isInstanceMethod: true).
        Parameters(0, returnType => returnType.Void(), parameters => { });

    BlobHandle parameterlessCtorBlobIndex = metadata.GetOrAddBlob(parameterlessCtorSignature);

    MemberReferenceHandle objectCtorMemberRef = metadata.AddMemberReference(
        systemObjectTypeRef,
        metadata.GetOrAddString(".ctor"),
        parameterlessCtorBlobIndex);

    // Create signature for "void Main()" method.
    var mainSignature = new BlobBuilder();

    new BlobEncoder(mainSignature).
        MethodSignature().
        Parameters(0, returnType => returnType.Void(), parameters => { });

    var methodBodyStream = new MethodBodyStreamEncoder(ilBuilder);

    var codeBuilder = new BlobBuilder();
    InstructionEncoder il;
    
    // Emit IL for Program::.ctor
    il = new InstructionEncoder(codeBuilder);

    // ldarg.0
    il.LoadArgument(0); 

    // call instance void [mscorlib]System.Object::.ctor()
    il.Call(objectCtorMemberRef);

    // ret
    il.OpCode(ILOpCode.Ret);

    int ctorBodyOffset = methodBodyStream.AddMethodBody(il);
    codeBuilder.Clear();

    // Emit IL for Program::Main
    var flowBuilder = new ControlFlowBuilder();
    il = new InstructionEncoder(codeBuilder, flowBuilder);

    // ldstr "hello"
    il.LoadString(metadata.GetOrAddUserString("Hello, world"));

    // call void [mscorlib]System.Console::WriteLine(string)
    il.Call(consoleWriteLineMemberRef);

    // ret
    il.OpCode(ILOpCode.Ret);

    int mainBodyOffset = methodBodyStream.AddMethodBody(il);
    codeBuilder.Clear();

    // Create method definition for Program::Main
    MethodDefinitionHandle mainMethodDef = metadata.AddMethodDefinition(
        MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig,
        MethodImplAttributes.IL,
        metadata.GetOrAddString("Main"),
        metadata.GetOrAddBlob(mainSignature),
        mainBodyOffset,
        parameterList: default(ParameterHandle));

    // Create method definition for Program::.ctor
    MethodDefinitionHandle ctorDef = metadata.AddMethodDefinition(
        MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName,
        MethodImplAttributes.IL,
        metadata.GetOrAddString(".ctor"),
        parameterlessCtorBlobIndex,
        ctorBodyOffset,
        parameterList: default(ParameterHandle));

    // Create type definition for the special <Module> type that holds global functions
    metadata.AddTypeDefinition(
        default(TypeAttributes),
        default(StringHandle),
        metadata.GetOrAddString("<Module>"),
        baseType: default(EntityHandle),
        fieldList: MetadataTokens.FieldDefinitionHandle(1),
        methodList: mainMethodDef);

    // Create type definition for ConsoleApplication.Program
    metadata.AddTypeDefinition(
        TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.AutoLayout | TypeAttributes.BeforeFieldInit,
        metadata.GetOrAddString("ConsoleApplication"),
        metadata.GetOrAddString("Program"),
        baseType: systemObjectTypeRef,
        fieldList: MetadataTokens.FieldDefinitionHandle(1),
        methodList: mainMethodDef);
    
    return mainMethodDef;
}

private static void WritePEImage(
    Stream peStream,
    MetadataBuilder metadataBuilder,
    BlobBuilder ilBuilder,
    MethodDefinitionHandle entryPointHandle
    )
{
    // Create executable with the managed metadata from the specified MetadataBuilder.
    var peHeaderBuilder = new PEHeaderBuilder(
        imageCharacteristics: Characteristics.ExecutableImage
        );

    var peBuilder = new ManagedPEBuilder(
        peHeaderBuilder,
        new MetadataRootBuilder(metadataBuilder),
        ilBuilder,
        entryPoint: entryPointHandle,
        flags: CorFlags.ILOnly,
        deterministicIdProvider: content => s_contentId);

    // Write executable into the specified stream.
    var peBlob = new BlobBuilder();
    BlobContentId contentId = peBuilder.Serialize(peBlob);
    peBlob.WriteContentTo(peStream);
}

public static void BuildHelloWorldApp()
{
    using var peStream = new FileStream(
        "ConsoleApplication.exe", FileMode.OpenOrCreate, FileAccess.ReadWrite
        );
    
    var ilBuilder = new BlobBuilder();
    var metadataBuilder = new MetadataBuilder();

    MethodDefinitionHandle entryPoint = EmitHelloWorld(metadataBuilder, ilBuilder);
    WritePEImage(peStream, metadataBuilder, ilBuilder, entryPoint);
}

설명

MetadataBuilder 클래스를 사용하면 프로그래밍 방식으로 어셈블리를 생성할 수 있습니다. 이러한 어셈블리는 .NET 5+ 및 .NET Core의 파일에 어셈블리 저장을 지원하지 않는 클래스에서 생성된 AssemblyBuilder 동적 어셈블리와 달리 파일에 저장할 수 있습니다.

API는 MetadataBuilder 테이블 또는 Blob과 같은 하위 수준 메타데이터 구문을 작동합니다. C#을 사용하여 어셈블리를 동적으로 생성하는 간단한 방법은 Roslyn API를 참조하세요 CSharpCompilation .

CLI 메타데이터의 형식은 ECMA-335 사양에 의해 정의됩니다. 자세한 내용은 Ecma International 웹 사이트의 표준 ECMA-335 - CLI(공용 언어 인프라) 를 참조하세요.

생성자

MetadataBuilder(Int32, Int32, Int32, Int32)

메타데이터 테이블 및 힙에 대한 작성기를 만듭니다.

메서드

AddAssembly(StringHandle, Version, StringHandle, BlobHandle, AssemblyFlags, AssemblyHashAlgorithm)

MetadataBuilder 클래스는 성능이 뛰어난 방식으로 어셈블리에 대한 메타데이터를 씁니다. 컴파일러 및 기타 어셈블리 생성 도구에서 사용하도록 설계되었습니다.

AddAssemblyFile(StringHandle, BlobHandle, Boolean)

MetadataBuilder 클래스는 성능이 뛰어난 방식으로 어셈블리에 대한 메타데이터를 씁니다. 컴파일러 및 기타 어셈블리 생성 도구에서 사용하도록 설계되었습니다.

AddAssemblyReference(StringHandle, Version, StringHandle, BlobHandle, AssemblyFlags, BlobHandle)

MetadataBuilder 클래스는 성능이 뛰어난 방식으로 어셈블리에 대한 메타데이터를 씁니다. 컴파일러 및 기타 어셈블리 생성 도구에서 사용하도록 설계되었습니다.

AddConstant(EntityHandle, Object)

매개 변수, 필드 또는 속성의 기본값을 추가합니다.

AddCustomAttribute(EntityHandle, EntityHandle, BlobHandle)

사용자 지정 특성을 추가합니다.

AddCustomDebugInformation(EntityHandle, GuidHandle, BlobHandle)

사용자 지정 디버그 정보를 추가합니다.

AddDeclarativeSecurityAttribute(EntityHandle, DeclarativeSecurityAction, BlobHandle)

형식, 메서드 또는 어셈블리에 선언적 보안 특성을 추가합니다.

AddDocument(BlobHandle, GuidHandle, BlobHandle, GuidHandle)

문서 디버그 정보를 추가합니다.

AddEncLogEntry(EntityHandle, EditAndContinueOperation)

MetadataBuilder 클래스는 성능이 뛰어난 방식으로 어셈블리에 대한 메타데이터를 씁니다. 컴파일러 및 기타 어셈블리 생성 도구에서 사용하도록 설계되었습니다.

AddEncMapEntry(EntityHandle)

MetadataBuilder 클래스는 성능이 뛰어난 방식으로 어셈블리에 대한 메타데이터를 씁니다. 컴파일러 및 기타 어셈블리 생성 도구에서 사용하도록 설계되었습니다.

AddEvent(EventAttributes, StringHandle, EntityHandle)

이벤트 정의를 추가합니다.

AddEventMap(TypeDefinitionHandle, EventDefinitionHandle)

MetadataBuilder 클래스는 성능이 뛰어난 방식으로 어셈블리에 대한 메타데이터를 씁니다. 컴파일러 및 기타 어셈블리 생성 도구에서 사용하도록 설계되었습니다.

AddExportedType(TypeAttributes, StringHandle, StringHandle, EntityHandle, Int32)

내보낸 형식을 추가합니다.

AddFieldDefinition(FieldAttributes, StringHandle, BlobHandle)

필드 정의를 추가합니다.

AddFieldLayout(FieldDefinitionHandle, Int32)

필드 정의의 필드 레이아웃을 정의합니다.

AddFieldRelativeVirtualAddress(FieldDefinitionHandle, Int32)

PE 이미지에 저장된 초기 값에 필드의 매핑을 추가합니다.

AddGenericParameter(EntityHandle, GenericParameterAttributes, StringHandle, Int32)

제네릭 매개 변수 정의를 추가합니다.

AddGenericParameterConstraint(GenericParameterHandle, EntityHandle)

제네릭 매개 변수에 형식 제약 조건을 추가합니다.

AddImportScope(ImportScopeHandle, BlobHandle)

로컬 범위 디버그 정보를 추가합니다.

AddInterfaceImplementation(TypeDefinitionHandle, EntityHandle)

형식에 인터페이스 구현을 추가합니다.

AddLocalConstant(StringHandle, BlobHandle)

지역 상수 디버그 정보를 추가합니다.

AddLocalScope(MethodDefinitionHandle, ImportScopeHandle, LocalVariableHandle, LocalConstantHandle, Int32, Int32)

로컬 범위 디버그 정보를 추가합니다.

AddLocalVariable(LocalVariableAttributes, Int32, StringHandle)

지역 변수 디버그 정보를 추가합니다.

AddManifestResource(ManifestResourceAttributes, StringHandle, EntityHandle, UInt32)

매니페스트 리소스를 추가합니다.

AddMarshallingDescriptor(EntityHandle, BlobHandle)

필드 또는 매개 변수에 마샬링 정보를 추가합니다.

AddMemberReference(EntityHandle, StringHandle, BlobHandle)

MemberRef 테이블 행을 추가합니다.

AddMethodDebugInformation(DocumentHandle, BlobHandle)

메서드 디버그 정보를 추가합니다.

AddMethodDefinition(MethodAttributes, MethodImplAttributes, StringHandle, BlobHandle, Int32, ParameterHandle)

메서드 정의를 추가합니다.

AddMethodImplementation(TypeDefinitionHandle, EntityHandle, EntityHandle)

형식 내의 메서드 선언에 대한 구현을 정의합니다.

AddMethodImport(MethodDefinitionHandle, MethodImportAttributes, StringHandle, ModuleReferenceHandle)

메서드 정의에 가져오기 정보를 추가합니다.

AddMethodSemantics(EntityHandle, MethodSemanticsAttributes, MethodDefinitionHandle)

메서드(getter, setter, adder 등)를 속성 또는 이벤트와 연결합니다.

AddMethodSpecification(EntityHandle, BlobHandle)

메서드 사양(인스턴스화)을 추가합니다.

AddModule(Int32, StringHandle, GuidHandle, GuidHandle, GuidHandle)

MetadataBuilder 클래스는 성능이 뛰어난 방식으로 어셈블리에 대한 메타데이터를 씁니다. 컴파일러 및 기타 어셈블리 생성 도구에서 사용하도록 설계되었습니다.

AddModuleReference(StringHandle)

MetadataBuilder 클래스는 성능이 뛰어난 방식으로 어셈블리에 대한 메타데이터를 씁니다. 컴파일러 및 기타 어셈블리 생성 도구에서 사용하도록 설계되었습니다.

AddNestedType(TypeDefinitionHandle, TypeDefinitionHandle)

지정된 형식 정의에 대한 중첩 관계를 정의합니다.

AddParameter(ParameterAttributes, StringHandle, Int32)

매개 변수 정의를 추가합니다.

AddProperty(PropertyAttributes, StringHandle, BlobHandle)

속성 정의를 추가합니다.

AddPropertyMap(TypeDefinitionHandle, PropertyDefinitionHandle)

MetadataBuilder 클래스는 성능이 뛰어난 방식으로 어셈블리에 대한 메타데이터를 씁니다. 컴파일러 및 기타 어셈블리 생성 도구에서 사용하도록 설계되었습니다.

AddStandaloneSignature(BlobHandle)

MetadataBuilder 클래스는 성능이 뛰어난 방식으로 어셈블리에 대한 메타데이터를 씁니다. 컴파일러 및 기타 어셈블리 생성 도구에서 사용하도록 설계되었습니다.

AddStateMachineMethod(MethodDefinitionHandle, MethodDefinitionHandle)

상태 시스템 메서드 디버그 정보를 추가합니다.

AddTypeDefinition(TypeAttributes, StringHandle, StringHandle, EntityHandle, FieldDefinitionHandle, MethodDefinitionHandle)

형식 정의를 추가합니다.

AddTypeLayout(TypeDefinitionHandle, UInt16, UInt32)

형식 정의의 형식 레이아웃을 정의합니다.

AddTypeReference(EntityHandle, StringHandle, StringHandle)

형식 참조를 추가합니다.

AddTypeSpecification(BlobHandle)

MetadataBuilder 클래스는 성능이 뛰어난 방식으로 어셈블리에 대한 메타데이터를 씁니다. 컴파일러 및 기타 어셈블리 생성 도구에서 사용하도록 설계되었습니다.

Equals(Object)

지정된 개체가 현재 개체와 같은지 확인합니다.

(다음에서 상속됨 Object)
GetHashCode()

기본 해시 함수로 작동합니다.

(다음에서 상속됨 Object)
GetOrAddBlob(BlobBuilder)

Blob 힙에 변경이 불가능한 바이트 배열의 지정된 Blob을 추가합니다(아직 없는 경우).

GetOrAddBlob(Byte[])

Blob 힙에 지정된 Blob을 추가합니다(아직 없는 경우).

GetOrAddBlob(ImmutableArray<Byte>)

Blob 힙에 바이트 배열의 지정된 Blob을 추가합니다(아직 없는 경우).

GetOrAddBlobUTF16(String)

UTF16 인코딩을 사용하여 문자열을 Blob으로 인코딩하고 Blob 힙에 추가합니다(아직 없는 경우).

GetOrAddBlobUTF8(String, Boolean)

UTF8 인코딩을 사용하여 문자열을 Blob으로 인코딩하고 Blob 힙에 추가합니다(아직 없는 경우).

GetOrAddConstantBlob(Object)

상수 값을 Blob으로 인코딩하고 Blob 힙에 추가합니다(아직 없는 경우). UTF16을 사용하여 문자열 상수를 인코딩합니다.

GetOrAddDocumentName(String)

디버그 문서 이름을 인코딩하고 Blob 힙에 추가합니다(아직 없는 경우).

GetOrAddGuid(Guid)

GUID 힙에 지정된 GUID를 추가합니다(아직 없는 경우).

GetOrAddString(String)

문자열 힙에 지정된 문자열을 추가합니다(아직 없는 경우).

GetOrAddUserString(String)

사용자 문자열 힙에 지정된 문자열을 추가합니다(아직 없는 경우).

GetRowCount(TableIndex)

지정된 테이블의 현재 항목 수를 반환합니다.

GetRowCounts()

각 테이블의 현재 항목 수를 반환합니다.

GetType()

현재 인스턴스의 Type을 가져옵니다.

(다음에서 상속됨 Object)
MemberwiseClone()

현재 Object의 단순 복사본을 만듭니다.

(다음에서 상속됨 Object)
ReserveGuid()

GUID 힙에 GUID를 위한 공간을 예약합니다.

ReserveUserString(Int32)

사용자 문자열 힙에 지정된 길이의 문자열을 위한 공간을 예약합니다.

SetCapacity(HeapIndex, Int32)

지정된 힙의 용량을 설정합니다.

SetCapacity(TableIndex, Int32)

지정된 테이블의 용량을 설정합니다.

ToString()

현재 개체를 나타내는 문자열을 반환합니다.

(다음에서 상속됨 Object)

적용 대상