DisassemblyData
Opisuje jedną instrukcję dezasemblacji dla zintegrowanego środowiska projektowego (IDE) do wyświetlenia.
Składnia
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;
};
Członkowie
dwFields
Stała DISASSEMBLY_STREAM_FIELDS określająca, które pola są wypełniane.
bstrAddress
Adres jako przesunięcie od punktu początkowego (zazwyczaj początek skojarzonej funkcji).
bstrCodeBytes
Bajty kodu dla tej instrukcji.
bstrOpcode
Kod opcode dla tej instrukcji.
bstrOperands
Operandy dla tej instrukcji.
bstrSymbol
Nazwa symbolu, jeśli istnieje, skojarzona z adresem (symbol publiczny, etykieta itd.).
uCodeLocationId
Identyfikator lokalizacji kodu dla tego dezasemblowanego wiersza. Jeśli adres kontekstu kodu jednego wiersza jest większy niż adres kontekstu kodu innego, zdezasemblowany identyfikator lokalizacji kodu pierwszego będzie również większy niż identyfikator lokalizacji kodu drugiego.
posBeg
TEXT_POSITION, który odpowiada pozycji w dokumencie, w którym zaczynają się dane dezasemblacji.
posEnd
TEXT_POSITION, który odpowiada pozycji w dokumencie, w którym kończą się dane dezasemblacji.
bstrDocumentUrl
W przypadku dokumentów tekstowych, które mogą być reprezentowane jako nazwy plików, bstrDocumentUrl
pole jest wypełniane nazwą pliku, w którym można znaleźć źródło, przy użyciu formatu file://file name
.
W przypadku dokumentów tekstowych, które nie mogą być reprezentowane jako nazwy plików, bstrDocumentUrl
jest unikatowym identyfikatorem dokumentu, a aparat debugowania musi zaimplementować metodę GetDocument .
To pole może również zawierać dodatkowe informacje o sumach kontrolnych. Aby uzyskać szczegółowe informacje, zobacz Uwagi.
dwByteOffset
Liczba bajtów instrukcji jest od początku wiersza kodu.
dwFlags
Stała DISASSEMBLY_FLAGS określająca, które flagi są aktywne.
Uwagi
Każda DisassemblyData
struktura opisuje jedną instrukcję dezasemblacji. Tablica tych struktur jest zwracana z metody Read .
Struktura TEXT_POSITION jest używana tylko dla dokumentów tekstowych. Zakres kodu źródłowego dla tej instrukcji jest wypełniany tylko dla pierwszej instrukcji wygenerowanej na podstawie instrukcji lub wiersza, na przykład, gdy dwByteOffset == 0
.
W przypadku dokumentów, które nie są tekstowe, kontekst dokumentu można uzyskać z kodu, a bstrDocumentUrl
pole powinno być wartością null. bstrDocumentUrl
Jeśli pole jest takie samo jak bstrDocumentUrl
pole w poprzednim DisassemblyData
elemecie tablicy, ustaw bstrDocumentUrl
wartość na wartość null.
dwFlags
Jeśli pole ma ustawioną flagęDF_DOCUMENT_CHECKSUM
, dodatkowe informacje sumy kontrolnej są zgodne z ciągiem wskazywany bstrDocumentUrl
przez pole. W szczególności po zakończeniu ciągu null następuje identyfikator GUID identyfikujący algorytm sumy kontrolnej, który z kolei następuje 4 bajty wskazujące liczbę bajtów w sumie kontrolnej, a po niej następuje bajty kontrolne. Zobacz przykład w tym temacie, aby dowiedzieć się, jak kodować i dekodować to pole w języku Visual C#.
Przykład
Pole bstrDocumentUrl
może zawierać dodatkowe informacje inne niż ciąg, jeśli flaga jest ustawiona DF_DOCUMENT_CHECKSUM
. Proces tworzenia i odczytywania tego zakodowanego ciągu jest prosty w języku Visual C++. Jednak w języku Visual C# jest to inna sprawa. Dla tych, którzy są ciekawi, poniższy przykład pokazuje jeden sposób na utworzenie zakodowanego ciągu z języka Visual C# i jeden sposób dekodowania zakodowanego ciągu w 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);
}
}
}
}
}