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
如果欄位與bstrDocumentUrl
上DisassemblyData
一個陣列元素中的欄位相同,請將 設定bstrDocumentUrl
為 Null 值。
dwFlags
如果字段已DF_DOCUMENT_CHECKSUM
設定旗標,則其他總和檢查碼資訊會遵循字段所指向的bstrDocumentUrl
字串。 具體來說,在 Null 字串終止符之後,接著會遵循 GUID 來識別總和檢查碼演算法,接著接著 4 個字節值,指出總和檢查碼中的位元組數目,接著接著總和檢查碼位元組。 請參閱本主題中的範例,以瞭解如何在Visual C# 中編碼和譯碼此欄位。
範例
如果設定旗標,DF_DOCUMENT_CHECKSUM
欄位bstrDocumentUrl
可以包含字串以外的其他資訊。 在 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);
}
}
}
}
}