mã ngoại lệ có cấu trúc được định nghĩa thông qua số NTSTATUS. Mặc dù ai đó từ MS suggests sử dụng FormatMessage() để chuyển đổi số NTSTATUS thành chuỗi, tôi sẽ không thực hiện việc này. Cờ FORMAT_MESSAGE_FROM_SYSTEM
được sử dụng để chuyển đổi kết quả của GetLastError() thành một chuỗi, do đó, nó không có ý nghĩa ở đây. Sử dụng cờ FORMAT_MESSAGE_FROM_HMODULE
cùng với ntdll.dll
sẽ dẫn đến kết quả không chính xác đối với một số mã. Ví dụ: đối với EXCEPTION_ACCESS_VIOLATION
, bạn sẽ nhận được The instruction at 0x
, không quá thông tin :).
Khi bạn xem các chuỗi được lưu trữ trong ntdll.dll
, điều hiển nhiên là nhiều chuỗi được cho là được sử dụng với hàm printf(), không phải với FormatMessage(). Ví dụ, chuỗi cho EXCEPTION_ACCESS_VIOLATION
là:
The instruction at 0x%08lx referenced memory at 0x%08lx. The memory could not be %s.
%0
được xử lý bởi FormatMessage() như dãy thoát nghĩa terminator tin nhắn, không một chèn. Chèn là% 1 đến% 99. Đó là lý do tại sao cờ FORMAT_MESSAGE_IGNORE_INSERTS
không tạo ra bất kỳ sự khác biệt nào.
Bạn có thể muốn tải các chuỗi từ ntdll.dll
và vượt qua nó để vprintf nhưng bạn sẽ cần phải chuẩn bị lập luận chính xác như các quy định cụ thể chuỗi (ví dụ cho EXCEPTION_ACCESS_VIOLATION
nó unsigned long
, unsigned long
, char*
). Và cách tiếp cận này có nhược điểm lớn: bất kỳ thay đổi về số lượng, thứ tự hoặc kích thước của đối số trong ntdll.dll
có thể phá vỡ mã của bạn.
Vì vậy, việc mã hóa các chuỗi thành mã của riêng bạn an toàn hơn và dễ dàng hơn. Tôi thấy nó nguy hiểm khi sử dụng dây được chuẩn bị bởi người khác mà không có sự phối hợp với tôi :) và hơn nữa cho chức năng khác. Đây chỉ là một khả năng nhiều hơn cho sự cố.
Có, 'FormatMessage' nên làm các trick. – avakar