winapi - 使用宏在 MessageBox 中显示 int 变量值
winapi - display int variable value in MessageBox using macros
出于调试目的,我试图制作一个简短的宏来显示各种类型,而不是不断复制所有 MessageBox
函数的参数。
对于字符串,我有以下宏:
#define DEBUG(x) MessageBox(NULL, x,"DEBUG",MB_ICONINFORMATION|MB_OK);
无论我传递变量(char
的数组)还是直接传递字符串,调用它都非常有效。
现在,我尝试为 int
做同样的事情。定义了这样的宏:
#define STRIGIFY(x) #x
#define TOSTRING(x) STRIGIFY(x)
#define DEBUGINT(x) DEBUG(TOSTRING(x))
它仅在我传递直接整数值时有效:
DEBUGINT(742);
但是,如果我传递 int
变量,MessageBox
显示变量名称而不是它的值:
int count = 3;
DEBUGINT(count);
我觉得很有趣的一点是,我可以在 DEBUGINT
宏中传递几乎任何东西,它仍然有效:
DEBUGINT(some unescaped string)
如何定义使用变量值而不是其名称的宏?
你不能。预处理器对变量或其值一无所知,因为它只在编译时 运行-time 不做任何事情。
您需要使用 sprintf
(或 VS 2015 中的 snprintf
)将变量 "print" 到缓冲区(char
的数组)并传递结果输出到 MessageBox
作为要显示的字符串。
您可以使用可变参数列表
#include <stdio.h>
void message(const char* format, ...)
{
int len;
char *buf;
va_list args;
va_start(args, format);
len = _vscprintf(format, args) + 1; //add room for terminating '[=10=]'
buf = (char*)malloc(len * sizeof(char));
vsprintf_s(buf, len, format, args);
MessageBoxA(0,buf,"debug",0);
//OutputDebugStringA(buf);
free(buf);
}
message("test %s %d %d %d", "str", 1, 2, 3);
您可能还想更改为 unicode 版本。
这并没有回答所提出的问题,但我会冒着声誉风险提出不同的解决方案。
请帮自己一个忙,不要使用 MessageBox()
或其他模式 UI 来显示调试信息。如果您确实想在那一点中断程序执行,请使用断点;它还允许您附加条件,这样您就不需要手动检查值。
如果您不想中断,只需使用 ::OutputDebugString()
将值打印到调试输出 window。如果附加了调试器,或者通过 DebugView
工具可以在调试器中看到它。
另一个小建议(针对 Visual Studio 用户):如果您在输出前加上源文件名和代码行号,双击输出中的该行 window 将你直接到那条线。只需在格式化字符串中使用 __FILE__
和 __LINE__
。
出于调试目的,我试图制作一个简短的宏来显示各种类型,而不是不断复制所有 MessageBox
函数的参数。
对于字符串,我有以下宏:
#define DEBUG(x) MessageBox(NULL, x,"DEBUG",MB_ICONINFORMATION|MB_OK);
无论我传递变量(char
的数组)还是直接传递字符串,调用它都非常有效。
现在,我尝试为 int
做同样的事情。定义了这样的宏:
#define STRIGIFY(x) #x
#define TOSTRING(x) STRIGIFY(x)
#define DEBUGINT(x) DEBUG(TOSTRING(x))
它仅在我传递直接整数值时有效:
DEBUGINT(742);
但是,如果我传递 int
变量,MessageBox
显示变量名称而不是它的值:
int count = 3;
DEBUGINT(count);
我觉得很有趣的一点是,我可以在 DEBUGINT
宏中传递几乎任何东西,它仍然有效:
DEBUGINT(some unescaped string)
如何定义使用变量值而不是其名称的宏?
你不能。预处理器对变量或其值一无所知,因为它只在编译时 运行-time 不做任何事情。
您需要使用 sprintf
(或 VS 2015 中的 snprintf
)将变量 "print" 到缓冲区(char
的数组)并传递结果输出到 MessageBox
作为要显示的字符串。
您可以使用可变参数列表
#include <stdio.h>
void message(const char* format, ...)
{
int len;
char *buf;
va_list args;
va_start(args, format);
len = _vscprintf(format, args) + 1; //add room for terminating '[=10=]'
buf = (char*)malloc(len * sizeof(char));
vsprintf_s(buf, len, format, args);
MessageBoxA(0,buf,"debug",0);
//OutputDebugStringA(buf);
free(buf);
}
message("test %s %d %d %d", "str", 1, 2, 3);
您可能还想更改为 unicode 版本。
这并没有回答所提出的问题,但我会冒着声誉风险提出不同的解决方案。
请帮自己一个忙,不要使用 MessageBox()
或其他模式 UI 来显示调试信息。如果您确实想在那一点中断程序执行,请使用断点;它还允许您附加条件,这样您就不需要手动检查值。
如果您不想中断,只需使用 ::OutputDebugString()
将值打印到调试输出 window。如果附加了调试器,或者通过 DebugView
工具可以在调试器中看到它。
另一个小建议(针对 Visual Studio 用户):如果您在输出前加上源文件名和代码行号,双击输出中的该行 window 将你直接到那条线。只需在格式化字符串中使用 __FILE__
和 __LINE__
。