msvc_sink.h 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  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. public:
  27. msvc_sink() = default;
  28. msvc_sink(bool check_debugger_present)
  29. : check_debugger_present_{check_debugger_present} {};
  30. protected:
  31. void sink_it_(const details::log_msg &msg) override {
  32. if (check_debugger_present_ && !IsDebuggerPresent()) {
  33. return;
  34. }
  35. memory_buf_t formatted;
  36. base_sink<Mutex>::formatter_->format(msg, formatted);
  37. formatted.push_back('\0'); // add a null terminator for OutputDebugString
  38. #if defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT)
  39. wmemory_buf_t wformatted;
  40. details::os::utf8_to_wstrbuf(string_view_t(formatted.data(), formatted.size()), wformatted);
  41. OutputDebugStringW(wformatted.data());
  42. #else
  43. OutputDebugStringA(formatted.data());
  44. #endif
  45. }
  46. void flush_() override {}
  47. bool check_debugger_present_ = true;
  48. };
  49. using msvc_sink_mt = msvc_sink<std::mutex>;
  50. using msvc_sink_st = msvc_sink<details::null_mutex>;
  51. using windebug_sink_mt = msvc_sink_mt;
  52. using windebug_sink_st = msvc_sink_st;
  53. } // namespace sinks
  54. } // namespace spdlog
  55. #endif