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
Константа DISASSE МБLY_STREAM_FIELDS, указывающая, какие поля заполняются.
bstrAddress
Адрес в качестве смещения от какой-то начальной точки (обычно начало связанной функции).
bstrCodeBytes
Байты кода для этой инструкции.
bstrOpcode
Код для этой инструкции.
bstrOperands
Операнды для этой инструкции.
bstrSymbol
Имя символа, связанное с адресом (общедоступным символом, меткой и т. д.).
uCodeLocationId
Идентификатор расположения кода для этой дизассемблированных строк. Если адрес контекста кода одной строки больше адреса контекста кода другого, то идентификатор расположения разобранного кода первой также будет больше идентификатора расположения кода второго.
posBeg
TEXT_POSITION, соответствующий позиции в документе, в котором начинается дизассемблирование данных.
posEnd
TEXT_POSITION, соответствующий позиции в документе, в котором заканчивается дизассемблирование данных.
bstrDocumentUrl
Для текстовых документов, которые можно представить в виде имен файлов, bstrDocumentUrl
поле заполняется именем файла, где можно найти источник, используя формат file://file name
.
Для текстовых документов, которые не могут быть представлены в виде имен файлов, bstrDocumentUrl
является уникальным идентификатором документа, а подсистема отладки должна реализовать метод GetDocument .
Это поле также может содержать дополнительные сведения о проверка sumsums. Дополнительные сведения см. в примечаниях.
dwByteOffset
Число байтов инструкции начинается с начала строки кода.
dwFlags
Константа DISASSE МБLY_FLAGS, указывающая, какие флаги активны.
Замечания
Каждая DisassemblyData
структура описывает одну инструкцию дизассембли. Массив этих структур возвращается из метода Read .
Структура TEXT_POSITION используется только для текстовых документов. Диапазон исходного кода для этой инструкции заполняется только для первой инструкции, созданной из инструкции или строки, например, когда dwByteOffset == 0
.
Для документов, не являющихся текстовыми, контекст документа можно получить из кода, а bstrDocumentUrl
поле должно иметь значение NULL. bstrDocumentUrl
Если поле совпадает с bstrDocumentUrl
полем в предыдущем DisassemblyData
элементе массива, задайте bstrDocumentUrl
значение NULL.
dwFlags
Если поле имеет набор флаговDF_DOCUMENT_CHECKSUM
, дополнительные сведения о проверка sum следует строке, на которую указывает bstrDocumentUrl
поле. В частности, после конца строки NULL следует GUID, определяющий алгоритм проверка sum, за которым в свою очередь следует 4-байтовое значение, указывающее количество байтов в проверка sum, за которым в свою очередь следует проверка байт. См. пример в этом разделе о том, как кодировать и декодировать это поле в 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);
}
}
}
}
}