如何在不包含Windows.h的情况下获取IsDebuggerPresent的声明?

时间:2017-05-28 22:52:34

标签: c++ windows visual-studio assert

这与How to install a DebugBreak handler?How to get a declaration for DebugBreak without including Windows.h?有关。我们希望使用IsDebuggerPresent()进行评估,以避免在没有调试器的情况下使用DebugBreak()时发生崩溃。

我们遇到的问题是,我们必须包含<windows.h>,并且即使定义了WIN32_LEAN_AND_MEAN,也会带来很多额外的问题。一些额外的错误,如minmax,打破了C ++编译。事实上,测试我们的变化打破了我们。

尝试使用简单的extern BOOL IsDebuggerPresent()进行操作需要大量的预处理器魔法,并且与函数的所有版本上的签名不匹配。考虑到我们希望确保&#34;事情正常工作&#34;对于15年的操作系统和编译器来说,这似乎是一个棘手的问题。

是否可以在不包含IsDebuggerPresent()的情况下使用<windows.h>?如果是这样,那我们该怎么做呢?

1 个答案:

答案 0 :(得分:0)

下面的代码是一个用于Windows的运行时dubugger,它最小化而不包括windows.h本身。我知道这并没有直接回答这个问题,但是为了让你的代码能够工作,你需要具体定义的是架构定义(预处理器的东西),以及<errhandlingapi.h><windef.h>。我不完全确定还有什么参考下面的例子:

我的代码:

#if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && !defined(_ARM_) && !defined(_ARM64_) && defined(_M_IX86)
#define _X86_
#if !defined(_CHPE_X86_ARM64_) && defined(_M_HYBRID)
#define _CHPE_X86_ARM64_
#endif
#endif

#if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && !defined(_ARM_) && !defined(_ARM64_) && defined(_M_AMD64)
#define _AMD64_
#endif

#if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && !defined(_ARM_) && !defined(_ARM64_) && defined(_M_ARM)
#define _ARM_
#endif

#if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && !defined(_ARM_) && !defined(_ARM64_) && defined(_M_ARM64)
#define _ARM64_
#endif

#if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && !defined(_ARM_) && !defined(_ARM64_) && defined(_M_M68K)
#define _68K_
#endif

#if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && !defined(_ARM_) && !defined(_ARM64_) && defined(_M_MPPC)
#define _MPPC_
#endif

#if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_M_IX86) && !defined(_AMD64_) && !defined(_ARM_) && !defined(_ARM64_) && defined(_M_IA64)
#if !defined(_IA64_)
#define _IA64_
#endif /* !_IA64_ */
#endif

#ifndef _MAC
#if defined(_68K_) || defined(_MPPC_)
#define _MAC
#endif
#endif
#include <string>
#include <windef.h>
#include <WinUser.h>
#include <WinNls.h>
#include <errhandlingapi.h>
#include <processthreadsapi.h>
#include <WinBase.h>

__pragma (comment(lib, "User32"));

namespace Microsoft {
void __stdcall rt_assert(const bool test, const wchar_t* FunctionName)
{
    if (test) return;

    // Retrieve the system error message for the last-error code
    unsigned __int32 ERROR_ID = GetLastError();
    void* MsgBuffer;
    LCID lcid; //language id
    GetLocaleInfoEx(L"en-US", LOCALE_RETURN_NUMBER | LOCALE_ILANGUAGE, (wchar_t*)&lcid, sizeof(lcid));

    //get error message and attach it to Msgbuffer
    FormatMessageW(
        FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL, ERROR_ID, lcid, (wchar_t*)&MsgBuffer, 0, NULL);

    //concatonate string to DisplayBuffer
    const std::wstring DisplayBuffer = (static_cast<std::wstring>(FunctionName) + L" failed with error " + std::to_wstring(ERROR_ID) + L": " + static_cast<const wchar_t*>(MsgBuffer)).c_str();

    // Display the error message and exit the process
    if (IsDebuggerPresent())
    {
        OutputDebugStringW(DisplayBuffer.c_str());
    }
    else
    {
        MessageBoxExW(NULL, DisplayBuffer.c_str(), L"Error", MB_ICONERROR | MB_OK, static_cast<unsigned __int16>(lcid));
    }
    ExitProcess(ERROR_ID);
}
}