求助,通过外部程序获取价格数据源到dll,然后mql从dll中实时获取价格数据如何实现接收?目前已有外部获取快速平台的数据源,这个数据源应该是把价格数据写入Dll中,但是mt4如何从这个dll中动态接收获取数据,代码怎么写?如何对接?如有能解决的高人,愿酬谢。
1 如果 DLL 能够独立于外部程序运行,即 DLL 里面包含了整个读取数据源的逻辑(连接、认证、读取、存储),那么直接用 #import 将 DLL 加载到 MQL4/5 程序里,并调用相关接口即可;
2 如果 DLL 必须依赖外部程序运行,但可以把数据写入到共享数据通道(文件,共享内存),那么用 MQL4/5 读取共享数据通道即可;
3 若以上两项都无法实现,改写 DLL 或自己编写抓数据代码吧。
1 如果 DLL 能够独立于外部程序运行,即 DLL 里面包含了整个读取数据源的逻辑(连接、认证、读取、存储),那么直接用 #import 将 DLL 加载到 MQL4/5 程序里,并调用相关接口即可;
2 如果 DLL 必须依赖外部程序运行,但可以把数据写入到共享数据通道(文件,共享内存),那么用 MQL4/5 读取共享数据通道即可;
3 若以上两项都无法实现,改写 DLL 或自己编写抓数据代码吧。
.def文件:
EXPORTS
getRates @1
.h文件:
#if !defined(_METATRADEREXT32_SUPP_H_00007000_INCLUDED_)
#define _METATRADEREXT32_SUPP_H_00007000_INCLUDED_
#if _MSC_VER > 1000 //编译器版本》1000
#pragma
once //只编译一次
#endif // _MSC_VER > 1000
#include <windows.h>
#pragma pack(push) //保存对齐状态
#pragma pack(1) //设定为1字节对齐
__declspec(align(16)) struct stMetaTraderExt32
{
UCHAR Header[0x1000];
UCHAR Text[0x2000];
UCHAR
Rdata[0x1000];
UCHAR Data[0x1000];
UCHAR Rsrc[0x1000];
UCHAR Reloc[0x1000];
};
#pragma pack(pop) //恢复对齐状态
__declspec(align(16)) extern stMetaTraderExt32 MetaTraderExt32;
/* Data for initialization. */
extern UCHAR MetaTraderExt32_InitData[0x80E];
extern HMODULE g_hMetaTraderExt32;
/*
Description: Access any address in the DLL.
Parameters:
rvaAddr: The RVA address you want to access.
*/
void*
__stdcall MetaTraderExt32_RVA(DWORD rvaAddr);
#define MetaTraderExt32_VA(vaAddr) MetaTraderExt32_RVA((vaAddr) - 0x10000000)
#endif // !defined(_METATRADEREXT32_SUPP_H_00007000_INCLUDED_)
.cpp文件:
#include "stdafx.h"
#include "MetaTraderExt32.h"
HMODULE g_hMetaTraderExt32;
BOOL (WINAPI *MetaTraderExt32_DllEntryPoint)(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID
lpReserved);
extern UCHAR MetaTraderExt32_text[0x2000];
extern UCHAR MetaTraderExt32_rdata[0x1000];
extern UCHAR
MetaTraderExt32_data[0x1000];
__declspec(align(16)) stMetaTraderExt32 MetaTraderExt32;
void* __stdcall MetaTraderExt32_RVA(DWORD rvaAddr)
{
if(rvaAddr==0)
return g_hMetaTraderExt32;
if(rvaAddr >= 0
&& rvaAddr < 0x7000)
return (UCHAR*)&MetaTraderExt32 + rvaAddr;
return NULL;
}
FARPROC __stdcall MetaTraderExt32_GetExport(LPCSTR lpExportName)
{
if(lstrcmpA(lpExportName,"getRates")==0)
return
(FARPROC)MetaTraderExt32_VA(0x10001790);
return NULL;
}
BOOL MetaTraderExt32_Init()
{
HMODULE hDll;
DWORD oldProtect;
void
(*fInitData)(HMODULE,void*,void*);
oldProtect = PAGE_EXECUTE_READWRITE;
VirtualProtect(&MetaTraderExt32,sizeof(MetaTraderExt32),PAGE_EXECUTE_READWRITE,&oldProtect);
memcpy(&MetaTraderExt32.Text,&MetaTraderExt32_text,sizeof(MetaTraderExt32_text));
memcpy(&MetaTraderExt32.Rdata,&MetaTraderExt32_rdata,sizeof(MetaTraderExt32_rdata));
memcpy(&MetaTraderExt32.Data,&MetaTraderExt32_data,sizeof(MetaTraderExt32_data));
hDll = ::LoadLibraryA("KERNEL32.dll");
if(!hDll)
{
#ifdef _DEBUG
MessageBoxA(NULL,
"Please copy the dependent
DLL \"KERNEL32.dll\" to the working directory.",
"Load DLL Failed",MB_OK|MB_ICONERROR);
#endif
ASSERT(0);
return FALSE;
}
*(FARPROC*)MetaTraderExt32_VA(0x10003000)
= ::GetProcAddress(hDll,"OpenFileMappingA");
if(!*(FARPROC*)MetaTraderExt32_VA(0x10003000))
return FALSE;
*(FARPROC*)MetaTraderExt32_VA(0x10003004) =
::GetProcAddress(hDll,"MapViewOfFile");
if(!*(FARPROC*)MetaTraderExt32_VA(0x10003004))
return FALSE;
*(FARPROC*)MetaTraderExt32_VA(0x10003008) =
::GetProcAddress(hDll,"UnmapViewOfFile");
if(!*(FARPROC*)MetaTraderExt32_VA(0x10003008))
return FALSE;
*(FARPROC*)MetaTraderExt32_VA(0x1000300C) =
::GetProcAddress(hDll,"CloseHandle");
if(!*(FARPROC*)MetaTraderExt32_VA(0x1000300C))
return FALSE;
*(FARPROC*)MetaTraderExt32_VA(0x10003010) =
::GetProcAddress(hDll,"GetCurrentThreadId");
if(!*(FARPROC*)MetaTraderExt32_VA(0x10003010))
return FALSE;
*(FARPROC*)MetaTraderExt32_VA(0x10003014) =
::GetProcAddress(hDll,"GetCurrentProcessId");
if(!*(FARPROC*)MetaTraderExt32_VA(0x10003014))
return FALSE;
*(FARPROC*)MetaTraderExt32_VA(0x10003018) =
::GetProcAddress(hDll,"QueryPerformanceCounter");
if(!*(FARPROC*)MetaTraderExt32_VA(0x10003018))
return FALSE;
*(FARPROC*)MetaTraderExt32_VA(0x1000301C) =
::GetProcAddress(hDll,"IsProcessorFeaturePresent");
if(!*(FARPROC*)MetaTraderExt32_VA(0x1000301C))
return FALSE;
*(FARPROC*)MetaTraderExt32_VA(0x10003020) =
::GetProcAddress(hDll,"IsDebuggerPresent");
if(!*(FARPROC*)MetaTraderExt32_VA(0x10003020))
return FALSE;
*(FARPROC*)MetaTraderExt32_VA(0x10003024) =
::GetProcAddress(hDll,"DecodePointer");
if(!*(FARPROC*)MetaTraderExt32_VA(0x10003024))
return FALSE;
*(FARPROC*)MetaTraderExt32_VA(0x10003028) =
::GetProcAddress(hDll,"EncodePointer");
if(!*(FARPROC*)MetaTraderExt32_VA(0x10003028))
return FALSE;
*(FARPROC*)MetaTraderExt32_VA(0x1000302C) =
::GetProcAddress(hDll,"GetSystemTimeAsFileTime");
if(!*(FARPROC*)MetaTraderExt32_VA(0x1000302C))
return FALSE;
hDll = ::LoadLibraryA("MSVCP120.dll");
if(!hDll)
{
#ifdef _DEBUG
MessageBoxA(NULL,
"Please copy the dependent
DLL \"MSVCP120.dll\" to the working directory.",
"Load DLL Failed",MB_OK|MB_ICONERROR);
#endif
ASSERT(0);
return FALSE;
}
*(FARPROC*)MetaTraderExt32_VA(0x10003034)
= ::GetProcAddress(hDll,"?_Winerror_map@std@@YAPBDH@Z");
if(!*(FARPROC*)MetaTraderExt32_VA(0x10003034))
return FALSE;
*(FARPROC*)MetaTraderExt32_VA(0x10003038) =
::GetProcAddress(hDll,"?_Xbad_alloc@std@@YAXXZ");
if(!*(FARPROC*)MetaTraderExt32_VA(0x10003038))
return FALSE;
*(FARPROC*)MetaTraderExt32_VA(0x1000303C) =
::GetProcAddress(hDll,"?_Xout_of_range@std@@YAXPBD@Z");
if(!*(FARPROC*)MetaTraderExt32_VA(0x1000303C))
return FALSE;
*(FARPROC*)MetaTraderExt32_VA(0x10003040) =
::GetProcAddress(hDll,"?_Xlength_error@std@@YAXPBD@Z");
if(!*(FARPROC*)MetaTraderExt32_VA(0x10003040))
return FALSE;
*(FARPROC*)MetaTraderExt32_VA(0x10003044) =
::GetProcAddress(hDll,"?_Syserror_map@std@@YAPBDH@Z");
if(!*(FARPROC*)MetaTraderExt32_VA(0x10003044))
return FALSE;
hDll = ::LoadLibraryA("MSVCR120.dll");
if(!hDll)
{
#ifdef _DEBUG
MessageBoxA(NULL,
"Please copy the dependent
DLL \"MSVCR120.dll\" to the working directory.",
"Load DLL Failed",MB_OK|MB_ICONERROR);
#endif
ASSERT(0);
return FALSE;
}
*(FARPROC*)MetaTraderExt32_VA(0x1000304C)
= ::GetProcAddress(hDll,"_calloc_crt");
if(!*(FARPROC*)MetaTraderExt32_VA(0x1000304C))
return FALSE;
*(FARPROC*)MetaTraderExt32_VA(0x10003050) =
::GetProcAddress(hDll,"__dllonexit");
if(!*(FARPROC*)MetaTraderExt32_VA(0x10003050))
return FALSE;
*(FARPROC*)MetaTraderExt32_VA(0x10003054) =
::GetProcAddress(hDll,"memmove");
if(!*(FARPROC*)MetaTraderExt32_VA(0x10003054))
return FALSE;
*(FARPROC*)MetaTraderExt32_VA(0x10003058) =
::GetProcAddress(hDll,"??1type_info@@UAE@XZ");
if(!*(FARPROC*)MetaTraderExt32_VA(0x10003058))
return FALSE;
*(FARPROC*)MetaTraderExt32_VA(0x1000305C) =
::GetProcAddress(hDll,"__CppXcptFilter");
if(!*(FARPROC*)MetaTraderExt32_VA(0x1000305C))
return FALSE;
*(FARPROC*)MetaTraderExt32_VA(0x10003060) =
::GetProcAddress(hDll,"_amsg_exit");
if(!*(FARPROC*)MetaTraderExt32_VA(0x10003060))
return FALSE;
*(FARPROC*)MetaTraderExt32_VA(0x10003064) =
::GetProcAddress(hDll,"free");
if(!*(FARPROC*)MetaTraderExt32_VA(0x10003064))
return FALSE;
*(FARPROC*)MetaTraderExt32_VA(0x10003068) =
::GetProcAddress(hDll,"_malloc_crt");
if(!*(FARPROC*)MetaTraderExt32_VA(0x10003068))
return FALSE;
*(FARPROC*)MetaTraderExt32_VA(0x1000306C) =
::GetProcAddress(hDll,"_unlock");
if(!*(FARPROC*)MetaTraderExt32_VA(0x1000306C))
return FALSE;
*(FARPROC*)MetaTraderExt32_VA(0x10003070) =
::GetProcAddress(hDll,"_initterm_e");
if(!*(FARPROC*)MetaTraderExt32_VA(0x10003070))
return FALSE;
*(FARPROC*)MetaTraderExt32_VA(0x10003074) =
::GetProcAddress(hDll,"_crt_debugger_hook");
if(!*(FARPROC*)MetaTraderExt32_VA(0x10003074))
return FALSE;
*(FARPROC*)MetaTraderExt32_VA(0x10003078) =
::GetProcAddress(hDll,"__crtUnhandledException");
if(!*(FARPROC*)MetaTraderExt32_VA(0x10003078))
return FALSE;
*(FARPROC*)MetaTraderExt32_VA(0x1000307C) =
::GetProcAddress(hDll,"__crtTerminateProcess");
if(!*(FARPROC*)MetaTraderExt32_VA(0x1000307C))
return FALSE;
*(FARPROC*)MetaTraderExt32_VA(0x10003080) =
::GetProcAddress(hDll,"_except_handler4_common");
if(!*(FARPROC*)MetaTraderExt32_VA(0x10003080))
return FALSE;
*(FARPROC*)MetaTraderExt32_VA(0x10003084) =
::GetProcAddress(hDll,"?terminate@@YAXXZ");
if(!*(FARPROC*)MetaTraderExt32_VA(0x10003084))
return FALSE;
*(FARPROC*)MetaTraderExt32_VA(0x10003088) =
::GetProcAddress(hDll,"__clean_type_info_names_internal");
if(!*(FARPROC*)MetaTraderExt32_VA(0x10003088))
return FALSE;
*(FARPROC*)MetaTraderExt32_VA(0x1000308C) =
::GetProcAddress(hDll,"_lock");
if(!*(FARPROC*)MetaTraderExt32_VA(0x1000308C))
return FALSE;
*(FARPROC*)MetaTraderExt32_VA(0x10003090) =
::GetProcAddress(hDll,"??2@YAPAXI@Z");
if(!*(FARPROC*)MetaTraderExt32_VA(0x10003090))
return FALSE;
*(FARPROC*)MetaTraderExt32_VA(0x10003094) =
::GetProcAddress(hDll,"??3@YAXPAX@Z");
if(!*(FARPROC*)MetaTraderExt32_VA(0x10003094))
return FALSE;
*(FARPROC*)MetaTraderExt32_VA(0x10003098) =
::GetProcAddress(hDll,"_initterm");
if(!*(FARPROC*)MetaTraderExt32_VA(0x10003098))
return FALSE;
*(FARPROC*)MetaTraderExt32_VA(0x1000309C) =
::GetProcAddress(hDll,"_purecall");
if(!*(FARPROC*)MetaTraderExt32_VA(0x1000309C))
return FALSE;
*(FARPROC*)MetaTraderExt32_VA(0x100030A0) =
::GetProcAddress(hDll,"_onexit");
if(!*(FARPROC*)MetaTraderExt32_VA(0x100030A0))
return FALSE;
*(FARPROC*)MetaTraderExt32_VA(0x100030A4) =
::GetProcAddress(hDll,"_CxxThrowException");
if(!*(FARPROC*)MetaTraderExt32_VA(0x100030A4))
return FALSE;
*(FARPROC*)MetaTraderExt32_VA(0x100030A8) =
::GetProcAddress(hDll,"__CxxFrameHandler3");
if(!*(FARPROC*)MetaTraderExt32_VA(0x100030A8))
return FALSE;
*(FARPROC*)MetaTraderExt32_VA(0x100030AC) =
::GetProcAddress(hDll,"memcpy");
if(!*(FARPROC*)MetaTraderExt32_VA(0x100030AC))
return FALSE;
*(FARPROC*)&fInitData = (FARPROC)&MetaTraderExt32_InitData[0];
fInitData(g_hMetaTraderExt32,MetaTraderExt32_RVA,MetaTraderExt32_GetExport);
*(FARPROC*)&MetaTraderExt32_DllEntryPoint = (FARPROC)MetaTraderExt32_VA(0x10002089);
return TRUE;
}
extern "C" __declspec(naked) void getRates(){__asm push offset MetaTraderExt32 + 0x1790 __asm ret}
/* Replace the default DllMain in dllmain.cpp */
BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call,
LPVOID lpReserved)
{
if(ul_reason_for_call==DLL_PROCESS_ATTACH)
{
g_hMetaTraderExt32 = hModule;
MetaTraderExt32_Init();
}
return MetaTraderExt32_DllEntryPoint(hModule,ul_reason_for_call,lpReserved);
}
直接抓内存就好了。