├── README.md ├── lib ├── WS2_32.Lib └── hiredis.lib ├── src └── mt4-redis │ ├── MT4RedisPlugin.cpp │ ├── MT4RedisPlugin.def │ ├── MT4RedisPlugin.h │ ├── MT4RedisPlugin.rc │ ├── MT4RedisPlugin.vcxproj │ ├── Resource.h │ ├── hiredis.h │ ├── libs │ └── hiredis.lib │ ├── res │ └── MT4RedisPlugin.rc2 │ ├── stdafx.cpp │ ├── stdafx.h │ └── targetver.h └── test └── Test.mq4 /README.md: -------------------------------------------------------------------------------- 1 | #Description 2 | a `hiredis` library wrapper for Using Redis in MT4. 3 | 4 | 5 | #Usage & Compile 6 | 1.Modify and Compile source code to a dll library (use Visual Studio 2010) 7 | 8 | 2.Import dll to MT4, Apply test EA to graph. 9 | 10 | 3.Test Redis connection if is work 11 | 12 | 13 | #License 14 | 15 | #####MT4-Redis is released under the Apache License 2.0. 16 | 17 | Copyright 2016 limc.cn All rights reserved. 18 | 19 | Licensed under the Apache License, Version 2.0 (the "License"); 20 | you may not use this file except in compliance with the License. 21 | You may obtain a copy of the License at 22 | 23 | http://www.apache.org/licenses/LICENSE-2.0 24 | 25 | Unless required by applicable law or agreed to in writing, software 26 | distributed under the License is distributed on an "AS IS" BASIS, 27 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 28 | See the License for the specific language governing permissions and 29 | limitations under the License. -------------------------------------------------------------------------------- /lib/WS2_32.Lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limccn/mt4-redis/000b2762d85aa0b61435fd30b7abe4e28ee29dd9/lib/WS2_32.Lib -------------------------------------------------------------------------------- /lib/hiredis.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limccn/mt4-redis/000b2762d85aa0b61435fd30b7abe4e28ee29dd9/lib/hiredis.lib -------------------------------------------------------------------------------- /src/mt4-redis/MT4RedisPlugin.cpp: -------------------------------------------------------------------------------- 1 |  2 | #include "stdafx.h" 3 | #include "MT4RedisPlugin.h" 4 | #include 5 | #include 6 | #include 7 | 8 | #include"hiredis.h" 9 | #pragma comment(lib, "hiredis.lib") 10 | #pragma comment(lib, "ws2_32.lib") 11 | 12 | 13 | #ifdef _DEBUG 14 | #define new DEBUG_NEW 15 | #endif 16 | 17 | #define REDIS_SERVER "127.0.0.1" 18 | #define REDIS_PORT 6379 19 | #define CONNECT_TIMEOUT 3000 20 | #define COMMAND_BUFFER 1024 21 | 22 | //+------------------------------------------------------------------+ 23 | //| Excute Redis Command "GET key" | 24 | //+------------------------------------------------------------------+ 25 | MT4_EXPFUNC wchar_t* __stdcall RedisGet(const wchar_t* key) 26 | { 27 | return RedisGetWithTimeout(key,CONNECT_TIMEOUT); 28 | } 29 | 30 | //+------------------------------------------------------------------+ 31 | //| Excute Redis Command "GET key" | 32 | //+------------------------------------------------------------------+ 33 | MT4_EXPFUNC wchar_t* __stdcall RedisGetWithTimeout(const wchar_t* key,int timeout) 34 | { 35 | // 构造windows socket对象 36 | //WSADATA wsaData; 37 | //WSAStartup(MAKEWORD(2,1), &wsaData); 38 | 39 | // 设置超时 40 | struct timeval tv; 41 | tv.tv_sec = timeout/1000; 42 | tv.tv_usec = timeout *1000; 43 | redisContext* context = redisConnectWithTimeout(REDIS_SERVER,REDIS_PORT,tv); 44 | 45 | 46 | //判断连接是否有错误 47 | if (context->err) { 48 | printf("Failed to connect redis server[%s:%d]\n",REDIS_SERVER,REDIS_PORT); 49 | redisFree(context); 50 | return NULL; 51 | } 52 | 53 | //构造Redis命令 54 | //获取size 55 | size_t len = wcslen(key) + 20; 56 | //命令长度 57 | if (len > COMMAND_BUFFER) { 58 | printf("Command is too long, Command string must short than %d",COMMAND_BUFFER); 59 | return NULL; 60 | } 61 | // 构建Comand 62 | wchar_t command[COMMAND_BUFFER]; 63 | //构造Redis命令 64 | wsprintf(command,L"GET %s",key); 65 | 66 | //字符串转换 67 | const char* command1 = WStr2CStr(command); 68 | 69 | //执行Redis命令 70 | printf("Ready to execute command[%s]\n", command1); 71 | 72 | // 执行命令 73 | redisReply* reply = (redisReply*)redisCommand(context, command1); 74 | 75 | //没有Redis响应 76 | if( NULL == reply) 77 | { 78 | printf("Failed to execute command[%s]\n",command1); 79 | redisFree(context); 80 | return NULL; 81 | } 82 | 83 | //响应状态 84 | if ( reply->type != REDIS_REPLY_STRING) 85 | { 86 | printf("Failed to execute command[%s]\n",command1); 87 | freeReplyObject(reply); 88 | redisFree(context); 89 | return NULL; 90 | } 91 | printf("The value of \"%s\" is \"%s\"\n", key, reply->str); 92 | 93 | //字符串转换 94 | wchar_t * result = CStr2WStr(reply->str); 95 | 96 | //释放Reply对象 97 | freeReplyObject(reply); 98 | //释放Redis连接 99 | redisFree(context); 100 | printf("Succeed to execute command[%s]\n", command1); 101 | delete command1; 102 | command1 = NULL; 103 | //返回结果字符串 104 | return result; 105 | } 106 | 107 | //+------------------------------------------------------------------+ 108 | //| Excute Redis Command "SET key value" | 109 | //+------------------------------------------------------------------+ 110 | MT4_EXPFUNC int __stdcall RedisSet(const wchar_t* key, const wchar_t* value) 111 | { 112 | return RedisSetWithTimeout(key, value, CONNECT_TIMEOUT); 113 | } 114 | 115 | //+------------------------------------------------------------------+ 116 | //| Excute Redis Command "SET key value" | 117 | //+------------------------------------------------------------------+ 118 | MT4_EXPFUNC int __stdcall RedisSetWithTimeout(const wchar_t* key, const wchar_t* value, int timeout) 119 | { 120 | //构造Redis命令 121 | //获取size 122 | size_t len = wcslen(key)+wcslen(value) + 20; 123 | //命令长度 124 | if (len > COMMAND_BUFFER) { 125 | printf("Command is too long, Command string must short than %d",COMMAND_BUFFER); 126 | return MT4_REDIS_CMD_FAILED; 127 | } 128 | // 构建Comand 129 | wchar_t command[COMMAND_BUFFER]; 130 | //构造Redis命令 131 | wsprintf(command,L"SET %s %s",key,value); 132 | return RedisCommandWithTimeout(command,timeout); 133 | } 134 | 135 | //+------------------------------------------------------------------+ 136 | //| Excute Redis Command | 137 | //+------------------------------------------------------------------+ 138 | MT4_EXPFUNC int __stdcall RedisCommand(const wchar_t* command) 139 | { 140 | //执行超时设置 141 | return RedisCommandWithTimeout(command, CONNECT_TIMEOUT); 142 | } 143 | 144 | //+------------------------------------------------------------------+ 145 | //| Excute Redis Command | 146 | //+------------------------------------------------------------------+ 147 | MT4_EXPFUNC int __stdcall RedisCommandWithTimeout(const wchar_t* command,int timeout) 148 | { 149 | // 构造windows socket对象 150 | //WSADATA wsaData; 151 | //WSAStartup(MAKEWORD(2,1), &wsaData); 152 | 153 | // 设置超时 154 | struct timeval tv; 155 | tv.tv_sec = timeout/1000; 156 | tv.tv_usec = timeout *1000; 157 | redisContext* context = redisConnectWithTimeout(REDIS_SERVER,REDIS_PORT,tv); 158 | 159 | //判断连接是否有错误 160 | if (context->err) { 161 | printf("Failed to connect redis server[%s:%d]\n",REDIS_SERVER,REDIS_PORT); 162 | redisFree(context); 163 | return MT4_REDIS_CMD_FAILED; 164 | } 165 | 166 | // 命令长度 167 | size_t len = wcslen(command) + 1; 168 | if (len > COMMAND_BUFFER) { 169 | printf("Command is too long, Command string must short than %d",COMMAND_BUFFER); 170 | redisFree(context); 171 | return MT4_REDIS_CMD_FAILED; 172 | } 173 | 174 | //字符串装换 175 | const char* command1 = WStr2CStr(command); 176 | 177 | //执行Redis命令 178 | printf("Ready to execute command[%s]\n", command1); 179 | 180 | // 执行命令 181 | redisReply* reply = (redisReply*)redisCommand(context, command1); 182 | 183 | //没有Redis响应 184 | if( NULL == reply) 185 | { 186 | printf("Failed to execute command[%s]\n",command1); 187 | redisFree(context); 188 | return MT4_REDIS_CMD_FAILED; 189 | } 190 | 191 | //响应状态 192 | if( !(reply->type == REDIS_REPLY_STATUS && _stricmp(reply->str,"OK")==0)) 193 | { 194 | printf("Failed to execute command[%s]\n",command1); 195 | freeReplyObject(reply); 196 | redisFree(context); 197 | return MT4_REDIS_CMD_FAILED; 198 | } 199 | 200 | //释放Reply对象 201 | freeReplyObject(reply); 202 | //释放Redis连接 203 | redisFree(context); 204 | printf("Succeed to execute command[%s]\n", command1); 205 | delete command1; 206 | command1 = NULL; 207 | //返回成功状态 208 | return MT4_REDIS_CMD_SUCCESSED; 209 | } 210 | 211 | //+------------------------------------------------------------------+ 212 | //| Test Redis if is working | 213 | //+------------------------------------------------------------------+ 214 | MT4_EXPFUNC int __stdcall RedisTest(const char* server, const int port) 215 | { 216 | redisContext* c = redisConnect(server, port); 217 | if ( c->err) 218 | { 219 | redisFree(c); 220 | printf("Connect to redisServer faile\n"); 221 | return MT4_REDIS_CMD_FAILED; 222 | } 223 | printf("Connect to redisServer Success\n"); 224 | 225 | const char* command1 = "set TESTKEY TESTVALUE"; 226 | redisReply* r = (redisReply*)redisCommand(c, command1); 227 | 228 | if( NULL == r) 229 | { 230 | printf("Execut command1 failure\n"); 231 | redisFree(c); 232 | return MT4_REDIS_CMD_FAILED; 233 | } 234 | if( !(r->type == REDIS_REPLY_STATUS && _stricmp(r->str,"OK")==0)) 235 | { 236 | printf("Failed to execute command[%s]\n",command1); 237 | freeReplyObject(r); 238 | redisFree(c); 239 | return MT4_REDIS_CMD_FAILED; 240 | } 241 | freeReplyObject(r); 242 | printf("Succeed to execute command[%s]\n", command1); 243 | 244 | redisFree(c); 245 | 246 | return 1; 247 | } 248 | 249 | //+------------------------------------------------------------------+ 250 | //| Show Messagebox | 251 | //+------------------------------------------------------------------+ 252 | static void MT4RedisMsgBox(const wchar_t* msg) 253 | { 254 | MessageBox(NULL,msg,L"MT4Redis",NULL); 255 | } 256 | 257 | 258 | //+------------------------------------------------------------------+ 259 | //| char to WCHAR 、wchar_t、LPWSTR etc | 260 | //+------------------------------------------------------------------+ 261 | static wchar_t * CStr2WStr(const char *cStr) 262 | { 263 | // MultiByteToWideChar( CP_ACP, 0, chr, 264 | // strlen(chr)+1, wchar, size/sizeof(wchar[0]) ); 265 | 266 | // First: get count of multi-byte string. 267 | const DWORD cCh = MultiByteToWideChar(CP_ACP, // Character Page. 268 | 0, // Flag, always be 0. 269 | cStr, // Multi-byte string. 270 | -1, // '-1' is to determind length automatically. 271 | NULL, // 'NULL' means ignore result. This is based 272 | // on next argument is '0'. 273 | 0); // '0' is to get the count of character needed 274 | // instead of to translate. 275 | 276 | // Second: allocate enough memory to save result in wide character. 277 | wchar_t* wStr = new wchar_t[cCh]; 278 | ZeroMemory(wStr, cCh * sizeof(wStr[0])); 279 | 280 | // Third: Translate it! 281 | MultiByteToWideChar(CP_ACP, // Character Page. 282 | 0, // Flag, always be 0. 283 | cStr, // Multi-byte string. 284 | -1, // Count of character of string above. 285 | wStr, // Target wide character buffer. 286 | cCh); // Count of character of wide character string buffer. 287 | 288 | return wStr; 289 | } 290 | 291 | 292 | //+------------------------------------------------------------------+ 293 | //| WCHAR 、wchar_t、LPWSTR to char | 294 | //+------------------------------------------------------------------+ 295 | static char* WStr2CStr(const wchar_t *wchar) 296 | { 297 | //WideCharToMultiByte( CP_ACP, 0, wchar, -1, 298 | // chr, length, NULL, NULL ); 299 | 300 | const DWORD cCh = WideCharToMultiByte(CP_ACP, 301 | 0, 302 | wchar, 303 | -1, 304 | NULL, 305 | 0, 306 | NULL, // When the wide character to be traslated 307 | // is not in code page, proc will use this 308 | // variable to fill with. We usually set it 309 | // to NULL. 310 | NULL); // This variable will save the number of 311 | // character which can't be tranlated. We 312 | // usually set it to NULL. 313 | 314 | // Second: allocate enough memory to save result. 315 | char* cStr = new char[cCh]; 316 | ZeroMemory(cStr, cCh * sizeof(cStr[0])); 317 | 318 | // Third: Translate it! 319 | WideCharToMultiByte(CP_ACP, 320 | 0, 321 | wchar, 322 | -1, 323 | cStr, 324 | cCh, 325 | NULL, 326 | NULL); 327 | 328 | return cStr; 329 | } 330 | 331 | //+------------------------------------------------------------------+ 332 | //| char to WCHAR 、wchar_t、LPWSTR etc | 333 | //+------------------------------------------------------------------+ 334 | //static char* WStr2CStr(const wchar_t* WStr) 335 | // { 336 | // 长度设置 337 | // size_t len = wcslen(WStr) + 1; 338 | // size_t converted = 0; 339 | // 准备转换的对象 340 | // char *CStr; 341 | // CStr=(char*)malloc(len*sizeof(char)); 342 | // 转换 343 | // wcstombs_s(&converted, CStr, len, WStr, _TRUNCATE); 344 | // 返回 345 | // return CStr; 346 | // } 347 | // 348 | //+------------------------------------------------------------------+ 349 | //| WCHAR 、wchar_t、LPWSTR to char | 350 | //+------------------------------------------------------------------+ 351 | //static wchar_t* CStr2WStr(const char* CStr) 352 | // { 353 | // 长度设置 354 | // size_t len = strlen(CStr) + 1; 355 | // size_t converted = 0; 356 | // 准备转换的对象 357 | // wchar_t *WStr; 358 | // WStr=(wchar_t*)malloc(len*sizeof(wchar_t)); 359 | // 转换 360 | // mbstowcs_s(&converted, WStr, len, CStr, _TRUNCATE); 361 | // 返回 362 | // return WStr; 363 | // } -------------------------------------------------------------------------------- /src/mt4-redis/MT4RedisPlugin.def: -------------------------------------------------------------------------------- 1 | LIBRARY MT4RedisPlugin 2 | 3 | EXPORTS 4 | RedisGet 5 | RedisGetWithTimeout 6 | RedisSet 7 | RedisSetWithTimeout 8 | RedisCommand 9 | RedisCommandWithTimeout 10 | RedisTest -------------------------------------------------------------------------------- /src/mt4-redis/MT4RedisPlugin.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef __AFXWIN_H__ 4 | #error "PCH ‚" 5 | #endif 6 | 7 | #include "resource.h" // 8 | 9 | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers 10 | 11 | 12 | #define MT4_REDIS_ERR -1 /* Error */ 13 | #define MT4_REDIS_OK 0 /* OK */ 14 | #define MT4_REDIS_ERR_IO 1 /* error in read or write */ 15 | #define MT4_REDIS_ERR_EOF 3 /* eof */ 16 | #define MT4_REDIS_ERR_PROTOCOL 4 /* protocol error */ 17 | #define MT4_REDIS_ERR_OTHER 2 /* something else */ 18 | 19 | #define MT4_REDIS_CMD_SUCCESSED 0 /* Successed */ 20 | #define MT4_REDIS_CMD_FAILED -1 /* Failed */ 21 | 22 | //--- 23 | #define MT4_EXPFUNC __declspec(dllexport) 24 | 25 | //+------------------------------------------------------------------+ 26 | //| Test Redis if is working | 27 | //+------------------------------------------------------------------+ 28 | MT4_EXPFUNC int __stdcall RedisTest(const char* server, const int port); 29 | 30 | //+------------------------------------------------------------------+ 31 | //| Excute Redis Command "GET key" | 32 | //+------------------------------------------------------------------+ 33 | MT4_EXPFUNC wchar_t* __stdcall RedisGet(const wchar_t* key); 34 | 35 | //+------------------------------------------------------------------+ 36 | //| Excute Redis Command "GET key" | 37 | //+------------------------------------------------------------------+ 38 | MT4_EXPFUNC wchar_t* __stdcall RedisGetWithTimeout(const wchar_t* key,int timeout); 39 | 40 | //+------------------------------------------------------------------+ 41 | //| Excute Redis Command "SET key value" | 42 | //+------------------------------------------------------------------+ 43 | MT4_EXPFUNC int __stdcall RedisSet(const wchar_t* key, const wchar_t* value); 44 | 45 | //+------------------------------------------------------------------+ 46 | //| Excute Redis Command "SET key value" | 47 | //+------------------------------------------------------------------+ 48 | MT4_EXPFUNC int __stdcall RedisSetWithTimeout(const wchar_t* key, const wchar_t* value,int timeout); 49 | 50 | //+------------------------------------------------------------------+ 51 | //| Excute Redis Command | 52 | //+------------------------------------------------------------------+ 53 | MT4_EXPFUNC int __stdcall RedisCommand(const wchar_t* command); 54 | 55 | //+------------------------------------------------------------------+ 56 | //| Excute Redis Command | 57 | //+------------------------------------------------------------------+ 58 | MT4_EXPFUNC int __stdcall RedisCommandWithTimeout(const wchar_t* command,int timeout); 59 | 60 | //+------------------------------------------------------------------+ 61 | //| char to WCHAR 、wchar_t、LPWSTR etc | 62 | //+------------------------------------------------------------------+ 63 | static wchar_t * CStr2WStr(const char *cStr); 64 | 65 | //+------------------------------------------------------------------+ 66 | //| WCHAR 、wchar_t、LPWSTR to char | 67 | //+------------------------------------------------------------------+ 68 | static char* WStr2CStr(const wchar_t *wchar); 69 | 70 | //+------------------------------------------------------------------+ 71 | //| Show Messagebox | 72 | //+------------------------------------------------------------------+ 73 | static void MT4RedisMsgBox(const wchar_t* msg); -------------------------------------------------------------------------------- /src/mt4-redis/MT4RedisPlugin.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limccn/mt4-redis/000b2762d85aa0b61435fd30b7abe4e28ee29dd9/src/mt4-redis/MT4RedisPlugin.rc -------------------------------------------------------------------------------- /src/mt4-redis/MT4RedisPlugin.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {343806EE-F92F-4A10-B5B2-2C2E138A4F27} 15 | MT4RedisPlugin 16 | MFCDLLProj 17 | 18 | 19 | 20 | DynamicLibrary 21 | true 22 | Unicode 23 | Dynamic 24 | 25 | 26 | DynamicLibrary 27 | false 28 | true 29 | Unicode 30 | Dynamic 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | Use 47 | Level3 48 | Disabled 49 | WIN32;_WINDOWS;_DEBUG;_USRDLL;%(PreprocessorDefinitions) 50 | MultiThreadedDLL 51 | ProgramDatabase 52 | 53 | 54 | Windows 55 | true 56 | .\MT4RedisPlugin.def 57 | $(ProjectDir)\libs;%(AdditionalLibraryDirectories) 58 | libcmt.lib;MSVCRT;%(IgnoreSpecificDefaultLibraries) 59 | 60 | 61 | false 62 | _DEBUG;%(PreprocessorDefinitions) 63 | 64 | 65 | 0x0411 66 | _DEBUG;%(PreprocessorDefinitions) 67 | $(IntDir);%(AdditionalIncludeDirectories) 68 | 69 | 70 | 71 | 72 | Level3 73 | Use 74 | MaxSpeed 75 | true 76 | true 77 | WIN32;_WINDOWS;NDEBUG;_USRDLL;%(PreprocessorDefinitions) 78 | MultiThreadedDLL 79 | 80 | 81 | Windows 82 | false 83 | true 84 | true 85 | .\MT4RedisPlugin.def 86 | $(ProjectDir)\libs;%(AdditionalLibraryDirectories) 87 | libcmt.lib;%(IgnoreSpecificDefaultLibraries) 88 | 89 | 90 | false 91 | NDEBUG;%(PreprocessorDefinitions) 92 | 93 | 94 | 0x0804 95 | NDEBUG;%(PreprocessorDefinitions) 96 | $(IntDir);%(AdditionalIncludeDirectories) 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | Create 107 | Create 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | -------------------------------------------------------------------------------- /src/mt4-redis/Resource.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limccn/mt4-redis/000b2762d85aa0b61435fd30b7abe4e28ee29dd9/src/mt4-redis/Resource.h -------------------------------------------------------------------------------- /src/mt4-redis/hiredis.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2010, Salvatore Sanfilippo 3 | * Copyright (c) 2010, Pieter Noordhuis 4 | * 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * * Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * * Neither the name of Redis nor the names of its contributors may be used 16 | * to endorse or promote products derived from this software without 17 | * specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 23 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 | * POSSIBILITY OF SUCH DAMAGE. 30 | */ 31 | 32 | #ifndef __HIREDIS_H 33 | #define __HIREDIS_H 34 | #include /* for size_t */ 35 | #include /* for va_list */ 36 | #ifndef _WIN32 37 | #include /* for struct timeval */ 38 | #endif 39 | #ifdef _WIN32 40 | #ifndef FD_SETSIZE 41 | #define FD_SETSIZE 16000 42 | #endif 43 | #include 44 | #include 45 | 46 | #ifndef va_copy 47 | #define va_copy(d,s) d = (s) 48 | #endif 49 | #endif 50 | 51 | #define HIREDIS_MAJOR 0 52 | #define HIREDIS_MINOR 9 53 | #define HIREDIS_PATCH 2 54 | 55 | #define REDIS_ERR -1 56 | #define REDIS_OK 0 57 | 58 | /* When an error occurs, the err flag in a context is set to hold the type of 59 | * error that occured. REDIS_ERR_IO means there was an I/O error and you 60 | * should use the "errno" variable to find out what is wrong. 61 | * For other values, the "errstr" field will hold a description. */ 62 | #define REDIS_ERR_IO 1 /* error in read or write */ 63 | #define REDIS_ERR_EOF 3 /* eof */ 64 | #define REDIS_ERR_PROTOCOL 4 /* protocol error */ 65 | #define REDIS_ERR_OTHER 2 /* something else */ 66 | 67 | /* Connection type can be blocking or non-blocking and is set in the 68 | * least significant bit of the flags field in redisContext. */ 69 | #define REDIS_BLOCK 0x1 70 | 71 | /* Connection may be disconnected before being free'd. The second bit 72 | * in the flags field is set when the context is connected. */ 73 | #define REDIS_CONNECTED 0x2 74 | 75 | /* The async API might try to disconnect cleanly and flush the output 76 | * buffer and read all subsequent replies before disconnecting. 77 | * This flag means no new commands can come in and the connection 78 | * should be terminated once all replies have been read. */ 79 | #define REDIS_DISCONNECTING 0x4 80 | 81 | /* Flag specific to the async API which means that the context should be clean 82 | * up as soon as possible. */ 83 | #define REDIS_FREEING 0x8 84 | 85 | /* Flag that is set when an async callback is executed. */ 86 | #define REDIS_IN_CALLBACK 0x10 87 | 88 | /* Flag that is set when the async context has one or more subscriptions. */ 89 | #define REDIS_SUBSCRIBED 0x20 90 | 91 | #define REDIS_REPLY_STRING 1 92 | #define REDIS_REPLY_ARRAY 2 93 | #define REDIS_REPLY_INTEGER 3 94 | #define REDIS_REPLY_NIL 4 95 | #define REDIS_REPLY_STATUS 5 96 | #define REDIS_REPLY_ERROR 6 97 | 98 | #ifdef __cplusplus 99 | extern "C" { 100 | #endif 101 | 102 | /* This is the reply object returned by redisCommand() */ 103 | typedef struct redisReply { 104 | int type; /* REDIS_REPLY_* */ 105 | long long integer; /* The integer when type is REDIS_REPLY_INTEGER */ 106 | int len; /* Length of string */ 107 | char *str; /* Used for both REDIS_REPLY_ERROR and REDIS_REPLY_STRING */ 108 | size_t elements; /* number of elements, for REDIS_REPLY_ARRAY */ 109 | struct redisReply **element; /* elements vector for REDIS_REPLY_ARRAY */ 110 | } redisReply; 111 | 112 | typedef struct redisReadTask { 113 | int type; 114 | int elements; /* number of elements in multibulk container */ 115 | int idx; /* index in parent (array) object */ 116 | void *obj; /* holds user-generated value for a read task */ 117 | struct redisReadTask *parent; /* parent task */ 118 | void *privdata; /* user-settable arbitrary field */ 119 | } redisReadTask; 120 | 121 | typedef struct redisReplyObjectFunctions { 122 | void *(*createString)(const redisReadTask*, char*, size_t); 123 | void *(*createArray)(const redisReadTask*, int); 124 | void *(*createInteger)(const redisReadTask*, long long); 125 | void *(*createNil)(const redisReadTask*); 126 | void (*freeObject)(void*); 127 | } redisReplyObjectFunctions; 128 | 129 | struct redisContext; /* need forward declaration of redisContext */ 130 | 131 | /* Context for a connection to Redis */ 132 | typedef struct redisContext { 133 | #ifdef _WIN32 134 | SOCKET fd; 135 | #else 136 | int fd; 137 | #endif 138 | int flags; 139 | char *obuf; /* Write buffer */ 140 | int err; /* Error flags, 0 when there is no error */ 141 | char *errstr; /* String representation of error when applicable */ 142 | 143 | /* Function set for reply buildup and reply reader */ 144 | redisReplyObjectFunctions *fn; 145 | void *reader; 146 | } redisContext; 147 | 148 | void freeReplyObject(void *reply); 149 | void *redisReplyReaderCreate(void); 150 | int redisReplyReaderSetReplyObjectFunctions(void *reader, redisReplyObjectFunctions *fn); 151 | int redisReplyReaderSetPrivdata(void *reader, void *privdata); 152 | void *redisReplyReaderGetObject(void *reader); 153 | char *redisReplyReaderGetError(void *reader); 154 | void redisReplyReaderFree(void *ptr); 155 | void redisReplyReaderFeed(void *reader, const char *buf, size_t len); 156 | int redisReplyReaderGetReply(void *reader, void **reply); 157 | 158 | /* Functions to format a command according to the protocol. */ 159 | int redisvFormatCommand(char **target, const char *format, va_list ap); 160 | int redisFormatCommand(char **target, const char *format, ...); 161 | int redisFormatCommandArgv(char **target, int argc, const char **argv, const size_t *argvlen); 162 | 163 | redisContext *redisConnect(const char *ip, int port); 164 | redisContext *redisConnectWithTimeout(const char *ip, int port, struct timeval tv); 165 | redisContext *redisConnectNonBlock(const char *ip, int port); 166 | redisContext *redisConnectUnix(const char *path); 167 | redisContext *redisConnectUnixWithTimeout(const char *path, struct timeval tv); 168 | redisContext *redisConnectUnixNonBlock(const char *path); 169 | redisContext *redisConnected(); 170 | redisContext *redisConnectedNonBlock(); 171 | int redisSetTimeout(redisContext *c, struct timeval tv); 172 | int redisSetReplyObjectFunctions(redisContext *c, redisReplyObjectFunctions *fn); 173 | void redisFree(redisContext *c); 174 | int redisBufferRead(redisContext *c); 175 | int redisBufferWrite(redisContext *c, int *done); 176 | int redisBufferReadDone(redisContext *c, char *buf, int nread); 177 | 178 | /* In a blocking context, this function first checks if there are unconsumed 179 | * replies to return and returns one if so. Otherwise, it flushes the output 180 | * buffer to the socket and reads until it has a reply. In a non-blocking 181 | * context, it will return unconsumed replies until there are no more. */ 182 | int redisGetReply(redisContext *c, void **reply); 183 | int redisGetReplyFromReader(redisContext *c, void **reply); 184 | 185 | /* Write a command to the output buffer. Use these functions in blocking mode 186 | * to get a pipeline of commands. */ 187 | void redisvAppendCommand(redisContext *c, const char *format, va_list ap); 188 | void redisAppendCommand(redisContext *c, const char *format, ...); 189 | void redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen); 190 | 191 | /* Issue a command to Redis. In a blocking context, it is identical to calling 192 | * redisAppendCommand, followed by redisGetReply. The function will return 193 | * NULL if there was an error in performing the request, otherwise it will 194 | * return the reply. In a non-blocking context, it is identical to calling 195 | * only redisAppendCommand and will always return NULL. */ 196 | void *redisvCommand(redisContext *c, const char *format, va_list ap); 197 | void *redisCommand(redisContext *c, const char *format, ...); 198 | void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen); 199 | 200 | #ifdef __cplusplus 201 | } 202 | #endif 203 | 204 | #endif 205 | -------------------------------------------------------------------------------- /src/mt4-redis/libs/hiredis.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limccn/mt4-redis/000b2762d85aa0b61435fd30b7abe4e28ee29dd9/src/mt4-redis/libs/hiredis.lib -------------------------------------------------------------------------------- /src/mt4-redis/res/MT4RedisPlugin.rc2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limccn/mt4-redis/000b2762d85aa0b61435fd30b7abe4e28ee29dd9/src/mt4-redis/res/MT4RedisPlugin.rc2 -------------------------------------------------------------------------------- /src/mt4-redis/stdafx.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limccn/mt4-redis/000b2762d85aa0b61435fd30b7abe4e28ee29dd9/src/mt4-redis/stdafx.cpp -------------------------------------------------------------------------------- /src/mt4-redis/stdafx.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limccn/mt4-redis/000b2762d85aa0b61435fd30b7abe4e28ee29dd9/src/mt4-redis/stdafx.h -------------------------------------------------------------------------------- /src/mt4-redis/targetver.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limccn/mt4-redis/000b2762d85aa0b61435fd30b7abe4e28ee29dd9/src/mt4-redis/targetver.h -------------------------------------------------------------------------------- /test/Test.mq4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limccn/mt4-redis/000b2762d85aa0b61435fd30b7abe4e28ee29dd9/test/Test.mq4 --------------------------------------------------------------------------------