Nếu bạn không muốn sử dụng lib đăng nhập hiện có, bạn có thể thử sử dụng macro. Tôi sẽ khuyên bạn nên cung cấp lib của riêng bạn và để làm cho nó có sẵn với các macro với printf như cơ chế định dạng.
Tôi đã làm điều tương tự như vậy trong quá khứ. Các macro được gọi là một đối tượng đăng nhập mà đóng gói đăng nhập thực sự có thể mở rộng thông qua plugin.
Nhưng tôi nghĩ rằng một cái gì đó tương tự đã được thực hiện bởi Log4xxx vì vậy có lẽ nó là tốt để nhìn vào nó.
Dưới đây là một đề nghị (xin lỗi không có thời gian để thử nghiệm, tôi hy vọng nó hoạt động)
tiêu đề:
#ifdef _MYAPI_IMPL
#define MY_API __declspec(dllexport)
#else
#define MY_API __declspec(dllimport)
#endif
class MY_API Log
{
public:
enum Level {Error, Warning, Info, Debug};
Log(Level level, const char* file, int line);
void operator()(const char* Format, ...);
private:
const char* m_file;
Level m_level;
int m_line;
};
#define __LOG(lvl) (Log(lvl, __FILE__, __LINE__))
#define LOG_ERR __LOG(Log::Error)
#define LOG_WRN __LOG(Log::Warning)
#define LOG_INF __LOG(Log::Info)
#define LOG_DBG __LOG(Log::Debug)
class My_API Logger
{
public:
virtual void log(const char* message)=0;
};
class MY_API LoggerManager
{
private:
static LoggerManager* s_inst;
LoggerManager() {}
virtual ~LoggerManager() {}
public:
static LoggerManager* Instance();
static void Clean();
addLogger(Logger* newLogger, Log::Level minlevel = Log::Info);
log(const char* file, int line, Log::Level level, const char* message);
};
Cpp:
Log::Log(Level level, const char* file, int line)
: m_file(file), m_level(level), m_line(line)
{
}
void Log::operator()(const char* format, ...)
{
va_list va;
va_start(va, format);
char message[LENGTH+1]={0};
_vsnprintf(message, LENGTH, format, va);
va_end(va);
LoggerManager::Instance()->log(m_file, m_line, m_level, message);
};
libs và exe khác sẽ có thể gọi như thế này Họ chỉ cần bao gồm .h và liên kết với lib.
LOG_INF("Hello %s!", "world");
Cập nhật: Tôi đã thêm giải thích cần thiết cho cơ chế ghi nhật ký. Một cách là sử dụng một singleton và để cung cấp một giao diện được phân lớp cho việc ghi nhật ký thực tế.
Lợi ích của việc sử dụng macro là nó cung cấp cho bạn khả năng lấy vị trí của nhật ký có thể là thông tin rất thú vị trong một số trường hợp. Cũng có thể biến macro thành printf thông thường khi bạn không muốn triển khai tất cả cơ chế ghi nhật ký.
Cảm ơn, giải pháp tốt đẹp! Tôi cũng có thể cung cấp nhật ký mặc định (ví dụ: syslog) nếu không có người dùng đăng nhập nào được đăng ký trong lib của tôi. –
yep. –