Есть самодельная тулза для c++, которая выводит некую отладочную информацию о состоянии регистров и значениях переменных, наподобие масмовских PrintDec/PrintHex/PrintString из VKDebug. Значения для вывода приходится передавать как в процедуру (собственно процедура и выводит), и передавать три параметра int Debug(LPSTR ValueName, int value, int Type); Передавать три параметра неудобно, кроме того приходится постоянно заниматься преобразованием типов передаваемых переменных в LPSTR и int. Может как-нибудь define пристегнуть к этому делу? Можно ли в этом говяжьем языке цэ придумать что-нибудь, чтобы можно было писать просто: PrintDec MyVar, без указания типа переменной и строки, содержащей её имя для отображения.
Можно перегрузить несколькими функциями: Код (Text): #define DBG_VAL(x) Debug(## x,x) int Debug(LPCSTR ValName,LPSTR StrValue); int Debug(LPCSTR ValName,int IntValue); int Debug(LPCSTR ValName,double DoubleValue); ... int var = 98; DBG_VAL(var); За корректность кода ручаться не могу, но общий смысл ясен: за счёт перегрузки функций избавляемся от параметра типа переменной, за счёт макроса — от имени переменной.
Идея понятна, а как реализовать - не понял Сама функция (на всякий случай): Код (Text): extern int Debug(LPSTR ValueName, int value, int Type){ char* fmt1=NULL; char buffer1[512]; char buffer2[512]; short crlf=0x0a0d; LPSTR StrValue=NULL; if (!FindDbg()) return 0; SendMessage (hDbgEdit, EM_SETSEL, -1, -1); switch (Type){ case 0: //----------- Print Decimal Value (Type==0) ------------ fmt1=" = %li"; break; case 1: //----------- Print Hexadecimal Value (Type==1) -------- fmt1=" = 0x%08lX"; break; case 2: //----------- Print String Value (Type==2) ------------- if (!IsBadReadPtr(ValueName,1)){ strcpy(buffer2,ValueName); strcat(buffer2," = "); StrValue=(LPSTR)VirtualAlloc(NULL,65536,MEM_COMMIT,PAGE_READWRITE); strcpy(StrValue,(LPSTR)value); strcat(buffer2,StrValue); } else { strcpy(buffer2,"Bad String Pointer!"); } strcat(buffer2,(const char*)&crlf); break; } if (Type !=2){ strcpy(buffer1, ValueName); strcat(buffer1, fmt1); wsprintf(buffer2,buffer1,value); strcat(buffer2,(const char*)&crlf); } SendMessage (hDbgEdit, EM_REPLACESEL, 0,(LPARAM)buffer2); if (NULL!=StrValue) VirtualFree(StrValue,65536,MEM_DECOMMIT); return 0; } Тип вывода dec/hex/string - это понятно, а как с именем переменной и её значением - нет. Код (Text): #define PrintDec (???) Debug(???, ???, 0); #define PrintHex (???) Debug(???, ???, 1); #define PrintString (???) Debug(???, ???, 2); Если просто сделать PrintDec(x), то ошибка: undefined symbol x, если описать её тип, то только один тип можно передавать. И как извлечь само имя переменной, кроме её значения?
Способов много. Вот например: Код (Text): void Debug(LPCSTR ValueName, int value, int Type) { printf("\tvariable: %s, type: %d, value: %X\n",ValueName,value,Type); } #define DBG_VAL(x) Debug(# x,x) void Debug(LPCSTR ValName,LPSTR StrValue) { Debug(ValName,(int)StrValue,2); } void Debug(LPCSTR ValName,int IntValue) { Debug(ValName,IntValue,0); } //void Debug(LPCSTR ValName,double DoubleValue); int main(int,char*) { char* sz = "hello, dword"; int n = strlen(sz); DBG_VAL(sz); DBG_VAL(n); printf(sz); return 0; } Хотя, идея вывода отладочный сообщений в диалог всегда претила мне и VKDebug не использовал. И для ассемблеров (масм/фасм), и для с++ написал такое: Код (Text): DebugFmt("calling X(): arg1(%d), arg2(%s)",arg1,arg2); У меня отладочные сообщения выводятся в OutputDebugString и/или лог-файл, иногда с автоматическим добавлением имени файла и номера строки. /offtop Жаль, RadASM не парсит сообщения компилятора, если ExitCode последнего равен 0 (success), а #pragma warning нет ни в масме, ни в фасме.
Здесь выход за границы буфера, если размер строки больше 65536. В этом случае лучше написать свою функцию, копирующую строки до 65536-го символа. _1868859233__Debug.rar
IceStudent Всё, сделал, спасибо. Саму функцию оставил без изменения и дальше так: int x; LPSTR sz; #define DBG_DEC(x) Debug(# x,x,0) #define DBG_HEX(x) Debug(# x,x,1) #define DBG_STR(sz) Debug(# sz,(int)sz,2) ... ... ... DBG_DEC(my_int); DBG_HEX(my_short); DBG_STR(my_string); _asm{int 3}; Всё выводит, как имя переменной, так и её значение SDragon Эта утилитка вряд ля кому ещё понадобится, а сам я помню про ограничение длины 65536