MQL 不支持可变参数宏,只能多定义模板函数,变通一下。
//+------------------------------------------------------------------+
//| cactus_log.mqh |
//| Copyright 2023, 100w123 |
//| https://100w123.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, 100w123"
#property link "https://100w123.com"
#property strict
#import "spdlog.dll"
void spdlog_info(string message);
void spdlog_debug(string message);
void spdlog_trace(string message);
void spdlog_warn(string message);
void spdlog_error(string message);
void spdlog_critical(string message);
void console_cls();
// 以下为了每个指标和 EA 都有自己单独的日志文件
int create_logger(string filename);
void destory_logger(int handle);
void log_info(int handle, string message);
void log_debug(int handle, string message);
void log_trace(int handle, string message);
void log_warn(int handle, string message);
void log_error(int handle, string message);
void log_critical(int handle, string message);
#import
template<typename T>
void LOG_INFO(T message) {
#ifdef SPDLOG
spdlog_info((string)message);
#else
Print((string)message);
#endif
}
template<typename T>
void LOG_DEBUG(T message) {
#ifdef SPDLOG
spdlog_debug((string)message);
#else
Print((string)message);
#endif
}
template<typename T>
void LOG_TRACE(T message) {
#ifdef SPDLOG
spdlog_trace((string)message);
#else
Print((string)message);
#endif
}
template<typename T>
void LOG_WARN(T message) {
#ifdef SPDLOG
spdlog_warn((string)message);
#else
Print((string)message);
#endif
}
template<typename T>
void LOG_ERROR(T message) {
#ifdef SPDLOG
spdlog_error((string)message);
#else
Print((string)message);
#endif
}
template<typename T>
void LOG_CRITICAL(T message) {
#ifdef SPDLOG
spdlog_critical((string)message);
#else
Print((string)message);
#endif
}
static int self_log_handle;
#ifdef SPDLOG
#define S_LOG_INIT() spdlog_init()
#define CONSOLE_CLS() console_cls()
#else
#define S_LOG_INIT()
#define CONSOLE_CLS()
#endif
void spdlog_init()
{
string filename = StringFormat("%s\\MQL4\\Logs\\%s_%s_%s.log", TerminalInfoString(TERMINAL_DATA_PATH), WindowExpertName(), Symbol(), GetPeriodStr(_Period));
self_log_handle = create_logger(filename);
}
template<typename T>
void S_LOG_INFO(T message) {
#ifdef SPDLOG
log_info(self_log_handle, (string)message);
#else
Print((string)message);
#endif
}
template<typename T>
void S_LOG_INFO(string format, T param1) {
#ifdef SPDLOG
log_info(self_log_handle, StringFormat(format, param1));
#else
PrintFormat(format, param1);
#endif
}
template<typename T1, typename T2>
void S_LOG_INFO(string format, T1 param1, T2 param2) {
#ifdef SPDLOG
log_info(self_log_handle, StringFormat(format, param1, param2));
#else
PrintFormat(format, param1, param2);
#endif
}
template<typename T1, typename T2, typename T3>
void S_LOG_INFO(string format, T1 param1, T2 param2, T3 param3) {
#ifdef SPDLOG
log_info(self_log_handle, StringFormat(format, param1, param2, param3));
#else
PrintFormat(format, param1, param2, param3);
#endif
}
template<typename T1, typename T2, typename T3, typename T4>
void S_LOG_INFO(string format, T1 param1, T2 param2, T3 param3, T4 param4) {
#ifdef SPDLOG
log_info(self_log_handle, StringFormat(format, param1, param2, param3, param4));
#else
PrintFormat(format, param1, param2, param3, param4);
#endif
}
template<typename T1, typename T2, typename T3, typename T4, typename T5>
void S_LOG_INFO(string format, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5) {
#ifdef SPDLOG
log_info(self_log_handle, StringFormat(format, param1, param2, param3, param4, param5));
#else
PrintFormat(format, param1, param2, param3, param4, param5);
#endif
}
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
void S_LOG_INFO(string format, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6) {
#ifdef SPDLOG
log_info(self_log_handle, StringFormat(format, param1, param2, param3, param4, param5, param6));
#else
PrintFormat(format, param1, param2, param3, param4, param5, param6);
#endif
}
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
void S_LOG_INFO(string format, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7) {
#ifdef SPDLOG
log_info(self_log_handle, StringFormat(format, param1, param2, param3, param4, param5, param7));
#else
PrintFormat(format, param1, param2, param3, param4, param5, param6, param7);
#endif
}
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
void S_LOG_INFO(string format, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8) {
#ifdef SPDLOG
log_info(self_log_handle, StringFormat(format, param1, param2, param3, param4, param5, param7, param8));
#else
PrintFormat(format, param1, param2, param3, param4, param5, param6, param7, param8);
#endif
}
template<typename T>
void S_LOG_DEBUG(T message) {
#ifdef SPDLOG
log_debug(self_log_handle, (string)message);
#else
Print((string)message);
#endif
}
template<typename T>
void S_LOG_TRACE(T message) {
#ifdef SPDLOG
log_trace(self_log_handle, (string)message);
#else
Print((string)message);
#endif
}
template<typename T>
void S_LOG_WARN(T message) {
#ifdef SPDLOG
log_warn(self_log_handle, (string)message);
#else
Print((string)message);
#endif
}
template<typename T>
void S_LOG_ERROR(T message) {
#ifdef SPDLOG
log_error(self_log_handle, (string)message);
#else
Print((string)message);
#endif
}
template<typename T>
void S_LOG_CRITICAL(T message) {
#ifdef SPDLOG
log_critical(self_log_handle, (string)message);
#else
Print((string)message);
#endif
}
调用方
#define SPDLOG // 如打印到 MT4 EA 标签栏,去掉宏
int OnInit() {
CONSOLE_CLS();
S_LOG_INIT();
S_LOG_INFO("%d %s", 123, "Hello World!");
return(INIT_SUCCEEDED);
}