msvc_sink.h 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. // Copyright(c) 2016 Alexander Dalshov & spdlog contributors.
  2. // Distributed under the MIT License (http://opensource.org/licenses/MIT)
  3. #pragma once
  4. #if defined(_WIN32)
  5. # include <spdlog/details/null_mutex.h>
  6. # if defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT)
  7. # include <spdlog/details/os.h>
  8. # endif
  9. # include <spdlog/sinks/base_sink.h>
  10. # include <mutex>
  11. # include <string>
  12. // Avoid including windows.h (https://stackoverflow.com/a/30741042)
  13. # if defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT)
  14. extern "C" __declspec(dllimport) void __stdcall OutputDebugStringW(const wchar_t *lpOutputString);
  15. # else
  16. extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA(const char *lpOutputString);
  17. # endif
  18. extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
  19. namespace spdlog {
  20. namespace sinks {
  21. /*
  22. * MSVC sink (logging using OutputDebugStringA)
  23. */
  24. template<typename Mutex>
  25. class msvc_sink : public base_sink<Mutex>
  26. {
  27. public:
  28. msvc_sink() = default;
  29. msvc_sink(bool check_debugger_present)
  30. : check_debugger_present_{check_debugger_present} {};
  31. protected:
  32. void sink_it_(const details::log_msg &msg) override
  33. {
  34. if (check_debugger_present_ && !IsDebuggerPresent())
  35. {
  36. return;
  37. }
  38. memory_buf_t formatted;
  39. base_sink<Mutex>::formatter_->format(msg, formatted);
  40. formatted.push_back('\0'); // add a null terminator for OutputDebugString
  41. # if defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT)
  42. wmemory_buf_t wformatted;
  43. details::os::utf8_to_wstrbuf(string_view_t(formatted.data(), formatted.size()), wformatted);
  44. OutputDebugStringW(wformatted.data());
  45. # else
  46. OutputDebugStringA(formatted.data());
  47. # endif
  48. }
  49. void flush_() override {}
  50. bool check_debugger_present_ = true;
  51. };
  52. using msvc_sink_mt = msvc_sink<std::mutex>;
  53. using msvc_sink_st = msvc_sink<details::null_mutex>;
  54. using windebug_sink_mt = msvc_sink_mt;
  55. using windebug_sink_st = msvc_sink_st;
  56. } // namespace sinks
  57. } // namespace spdlog
  58. #endif