次の方法で共有


DisassemblyData

統合開発環境 (IDE) で表示する 1 つの逆アセンブリ命令を記述します。

構文

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
この命令のオペコード。

bstrOperands
この命令のオペランド。

bstrSymbol
アドレスに関連付けられているシンボル名 (存在する場合) (パブリック シンボル、ラベルなど)。

uCodeLocationId
この逆アセンブルされた行のコードの場所識別子。 ある行のコード コンテキスト アドレスが別の行のコード コンテキスト アドレスより大きい場合、最初の行の逆アセンブルされたコードの場所識別子も、2 番目のコードの場所識別子より大きくなります。

posBeg
逆アセンブリ データが開始するドキュメント内の位置に対応する TEXT_POSITION

posEnd
逆アセンブリ データが終了するドキュメント内の位置に対応する TEXT_POSITION

bstrDocumentUrl
ファイル名として表すことができるテキスト ドキュメントの場合、bstrDocumentUrl フィールドには、file://file name の形式を使用して、ソースがあるファイル名が入力されます。

ファイル名として表現できないテキスト ドキュメントの場合は、bstrDocumentUrl はドキュメントの一意識別子であり、デバッグ エンジンでは GetDocument メソッドを実装する必要があります。

このフィールドには、チェックサムに関する追加情報を含めることもできます。 詳細については、「解説」を参照してください。

dwByteOffset
コード行の先頭からの命令があるバイト数。

dwFlags
アクティブなフラグを指定する DISASSEMBLY_FLAGS 定数。

解説

DisassemblyData 構造体は、逆アセンブリの 1 つの命令を記述します。 これらの構造体の配列は、Read メソッドから返されます。

TEXT_POSITION構造体は、テキストベースのドキュメントでのみ使用されます。 この命令のソース コードの範囲は、dwByteOffset == 0 の場合など、ステートメントまたは行から生成された最初の命令に対してのみ入力されます。

テキスト以外のドキュメントでは、コードからドキュメント コンテキストを取得でき、bstrDocumentUrl フィールドは null 値にする必要があります。 bstrDocumentUrl フィールドが前の DisassemblyData 配列要素の bstrDocumentUrl フィールドと同じ場合は、bstrDocumentUrl を null 値に設定します。

dwFlags フィールドに DF_DOCUMENT_CHECKSUM フラグが設定されている場合は、bstrDocumentUrl フィールドが指す文字列の後に追加のチェックサム情報が続きます。 具体的には、null 文字列ターミネータの後に、チェックサム アルゴリズムを識別する GUID が続き、次にその後にチェックサムのバイト数を示す 4 バイトの値が続き、次にその後にチェックサム バイトが続きます。 Visual C# でこのフィールドをエンコードおよびデコードする方法については、このトピックの例を参照してください。

DF_DOCUMENT_CHECKSUM フラグが設定されている場合、bstrDocumentUrl フィールドには文字列以外の追加情報を含めることができます。 このエンコードされた文字列の作成と読み取りのプロセスは、Visual C++ では簡単です。 ただし、Visual C# では、別問題です。 興味のあるユーザーは、次の例に、Visual C# からエンコードされた文字列を作成する 1 つの方法と、Visual C# でエンコードされた文字列をデコードする 1 つの方法を示しています。

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);
                }
            }
        }
    }
}

関連項目