다음을 통해 공유


DisassemblyData

표시할 IDE(통합 개발 환경)에 대한 디스어셈블리 명령 하나를 설명합니다.

구문

public struct DisassemblyData { 
    public uint          dwFields;
    public string        bstrAddress;
    public string        bstrAddressOffset;
    public string        bstrCodeBytes;
    public string        bstrOpcode;
    public string        bstrOperands;
    public string        bstrSymbol;
    public ulong         uCodeLocationId;
    public TEXT_POSITION posBeg;
    public TEXT_POSITION posEnd;
    public string        bstrDocumentUrl;
    public uint          dwByteOffset;
    public uint          dwFlags;
};

멤버

dwFields
입력할 필드를 지정하는 DISASSEMBLY_STREAM_FIELDS 상수입니다.

bstrAddress
주소는 일부 시작점(일반적으로 연결된 함수의 시작 부분)의 오프셋입니다.

bstrCodeBytes
이 명령의 코드 바이트입니다.

bstrOpcode
이 명령의 opcode입니다.

bstrOperands
이 명령의 피연산자입니다.

bstrSymbol
주소(공용 기호, 레이블 등)와 연결된 기호 이름(있는 경우)입니다.

uCodeLocationId
이 디스어셈블된 줄의 코드 위치 식별자입니다. 한 줄의 코드 컨텍스트 주소가 다른 줄의 코드 컨텍스트 주소보다 크면 첫 번째 줄의 디스어셈블된 코드 위치 식별자도 두 번째 줄의 코드 위치 식별자보다 큽니다.

posBeg
디스어셈블리 데이터가 시작되는 문서의 위치에 해당하는 TEXT_POSITION입니다.

posEnd
디스어셈블리 데이터가 끝나는 문서의 위치에 해당하는 TEXT_POSITION입니다.

bstrDocumentUrl
파일 이름으로 표시할 수 있는 텍스트 문서의 경우 bstrDocumentUrl 필드는 file://file name 형식을 사용하여 원본을 찾을 수 있는 파일 이름으로 채워집니다.

파일 이름으로 나타낼 수 없는 텍스트 문서의 경우 bstrDocumentUrl은 문서의 고유 식별자이며 디버그 엔진은 GetDocument 메서드를 구현해야 합니다.

이 필드에는 체크섬에 대한 추가 정보가 포함될 수도 있습니다. 자세한 내용은 설명을 참조하세요.

dwByteOffset
명령이 코드 줄의 시작에서 가져온 바이트 수입니다.

dwFlags
활성 상태인 플래그를 지정하는 DISASSEMBLY_FLAGS 상수입니다.

설명

DisassemblyData 구조는 디스어셈블리의 한 가지 지침을 설명합니다. 이러한 구조체의 배열은 Read 메서드에서 반환됩니다.

TEXT_POSITION 구조체는 텍스트 기반 문서에만 사용됩니다. 이 명령의 소스 코드 범위는 문 또는 줄에서 생성된 첫 번째 명령(예: dwByteOffset == 0인 경우)에 대해서만 채워집니다.

텍스트가 아닌 문서의 경우 코드에서 문서 컨텍스트를 가져올 수 있으며 bstrDocumentUrl 필드는 null 값이어야 합니다. bstrDocumentUrl 필드가 이전 DisassemblyData 배열 요소의 bstrDocumentUrl 필드와 같으면 bstrDocumentUrl을 null 값으로 설정합니다.

dwFlags 필드에 DF_DOCUMENT_CHECKSUM 플래그가 설정된 경우 bstrDocumentUrl 필드가 가리키는 문자열 뒤에 추가 체크섬 정보가 추가됩니다. 특히 null 문자열 종결자 뒤에는 체크섬 알고리즘을 식별하는 GUID와 체크섬의 바이트 수를 나타내는 4바이트 값이 차례로 표시되고 그 뒤에 체크섬 바이트가 옵니다. Visual C#에서 이 필드를 인코딩하고 디코딩하는 방법은 이 항목의 예제를 참조하세요.

예시

bstrDocumentUrl 필드는 DF_DOCUMENT_CHECKSUM 플래그가 설정된 경우 문자열 이외의 추가 정보를 포함할 수 있습니다. 이 인코딩된 문자열을 만들고 읽는 프로세스는 Visual C++에서 간단합니다. 그러나 Visual C#에서는 또 다른 문제입니다. 호기심이 많은 사용자를 위해 다음 예제에서는 Visual C#에서 인코딩된 문자열을 만드는 한 가지 방법과 Visual C#에서 인코딩된 문자열을 디코딩하는 한 가지 방법을 보여 줍니다.

using System;
using System.Runtime.InteropServices;

namespace MyNamespace
{
    class MyClass
    {
        string EncodeData(string documentString,
                          Guid checksumGuid,
                          byte[] checksumData)
        {
            string returnString = documentString;

            if (checksumGuid == null || checksumData == null)
            {
                // Nothing more to do. Just return the string.
                return returnString;
            }

            returnString += '\0'; // separating null value

            // Add checksum GUID to string.
            byte[] guidDataArray  = checksumGuid.ToByteArray();
            int    guidDataLength = guidDataArray.Length;
            IntPtr pBuffer        = Marshal.AllocCoTaskMem(guidDataLength);
            for (int i = 0; i < guidDataLength; i++)
            {
                Marshal.WriteByte(pBuffer, i, guidDataArray[i]);
            }
            // Copy guid data bytes to string as wide characters.
            // Assumption: sizeof(char) == 2.
            for (int i = 0; i < guidDataLength / sizeof(char); i++)
            {
                returnString += (char)Marshal.ReadInt16(pBuffer, i * sizeof(char));
            }

            // Add checksum count (a 32-bit value).
            Int32 checksumCount = checksumData.Length;
            Marshal.StructureToPtr(checksumCount, pBuffer, true);
            for (int i = 0; i < sizeof(Int32) / sizeof(char); i++)
            {
                returnString += (char)Marshal.ReadInt16(pBuffer, i * sizeof(char));
            }

            // Add checksum data.
            pBuffer = Marshal.AllocCoTaskMem(checksumCount);
            for (int i = 0; i < checksumCount; i++)
            {
                Marshal.WriteByte(pBuffer, i, checksumData[i]);
            }
            for (int i = 0; i < checksumCount / sizeof(char); i++)
            {
                returnString += (char)Marshal.ReadInt16(pBuffer, i * sizeof(char));
            }
            Marshal.FreeCoTaskMem(pBuffer);

            return returnString;
        }

        void DecodeData(    string encodedString,
                        out string documentString,
                        out Guid   checksumGuid,
                        out byte[] checksumData)
        {
            documentString = String.Empty;
            checksumGuid = Guid.Empty;
            checksumData = null;

            IntPtr pBuffer = Marshal.StringToBSTR(encodedString);
            if (null != pBuffer)
            {
                int bufferOffset = 0;

                // Parse string out. String is assumed to be Unicode.
                documentString = Marshal.PtrToStringUni(pBuffer);
                bufferOffset += (documentString.Length + 1) * sizeof(char);

                // Parse Guid out.
                // Read guid bytes from buffer and store in temporary
                // buffer that contains only the guid bytes. Then the
                // Marshal.PtrToStructure() can work properly.
                byte[] guidDataArray  = checksumGuid.ToByteArray();
                int    guidDataLength = guidDataArray.Length;
                IntPtr pGuidBuffer    = Marshal.AllocCoTaskMem(guidDataLength);
                for (int i = 0; i < guidDataLength; i++)
                {
                    Marshal.WriteByte(pGuidBuffer, i,
                                      Marshal.ReadByte(pBuffer, bufferOffset + i));
                }
                bufferOffset += guidDataLength;
                checksumGuid = (Guid)Marshal.PtrToStructure(pGuidBuffer, typeof(Guid));
                Marshal.FreeCoTaskMem(pGuidBuffer);

                // Parse out the number of checksum data bytes (always 32-bit value).
                int dataCount = Marshal.ReadInt32(pBuffer, bufferOffset);
                bufferOffset += sizeof(Int32);

                // Parse out the checksum data.
                checksumData = new byte[dataCount];
                for (int i = 0; i < dataCount; i++)
                {
                    checksumData[i] = Marshal.ReadByte(pBuffer, bufferOffset + i);
                }
            }
        }
    }
}

참고 항목