Somebody asked about doing Named Pipes from MT4 to communicate with another program, so here is the interface and some sample code. This is a DLL-free solution, using only MQL4. This assumes you're familiar with named pipes already. If you're not, you can read about them at http://msdn.microsoft.com/en-us/library/aa365780(VS.85).aspx
I really should make this into a library, but I don't have time right now. If someone wants to do that, feel free.
First the interface:
To open the pipe as a client, do the following:
To Read from the pipe is a little tricky. You can't read directly into strings, so I read into a int array, then convert the array to a string.:
And to write to the pipe:
I really should make this into a library, but I don't have time right now. If someone wants to do that, feel free.
First the interface:
Inserted Code
string PipeNamePrefix="\\\\.\\pipe\\"; int BufferSize = 256; #define PIPE_ACCESS_INBOUND 1 #define PIPE_ACCESS_OUTBOUND 2 #define PIPE_ACCESS_DUPLEX 3 #define PIPE_TYPE_BYTE 0 #define PIPE_TYPE_MESSAGE 4 #define PIPE_READMODE_BYTE 0 #define PIPE_READMODE_MESSAGE 2 #define PIPE_WAIT 0 #define PIPE_NOWAIT 1 #define INVALID_HANDLE_VALUE 0xffffffff #define GenericRead 0x80000000 #define GenericWrite 0x40000000 #define OPEN_EXISTING 3 extern string PipeName="MetaTrader"; int PipeHandle = INVALID_HANDLE_VALUE; int Buffer[64]; // 4 bytes/int * 64 = 256 #import "kernel32.dll" int CreateNamedPipeA(string pipeName, int openMode, int pipeMode, int maxInstances, int outBufferSize, int inBufferSize, int defaultTimeOut, int security ); int WaitNamedPipeA( string lpNamedPipeName, int nTimeOut ); bool PeekNamedPipe( int pipeHandle, int& buffer[], int bufferSize, int& bytesRead[], int& totalBytesAvail[], int& bytesLeftThisMessage[] ); int CreateFileA( string name, int desiredAccess, int SharedMode, int security, int creation, int flags, int templateFile ); int WriteFile( int fileHandle, int& buffer[], int bytes, int& numOfBytes[], int overlapped ); int ReadFile( int fileHandle, int& buffer[], int bytes, int& numOfBytes[], int overlapped ); int CloseHandle( int fileHandle ); int GetError(); #import
Inserted Code
FullPipeName = PipeNamePrefix + PipeName; if ( PipeHandle == INVALID_HANDLE_VALUE ) { if ( WaitNamedPipeA( FullPipeName, 1 ) == 0 ) { //Print( "No pipe available" ); return; } PipeHandle = CreateFileA( FullPipeName, GenericRead|GenericWrite, 0, 0, OPEN_EXISTING, 0, 0 ); Print( Symbol(), ": PipeHandle=", PipeHandle ); if ( PipeHandle == INVALID_HANDLE_VALUE ){ Print( "Pipe open failed" ); return; } }
Inserted Code
ReadFile( PipeHandle, Buffer, BufferSize, bytesRead, 0 ); message = StringFromBuffer(bytesRead[0]); string StringFromBuffer(int length) { string message = ""; for ( int i = 0; i < length; i++ ) { int c = Buffer[i / 4]; int off = i % 4; int shift = 0; if ( off == 1 ) shift = 8; else if ( off == 2 ) shift = 16; else if ( off == 3 ) shift = 24; c = (c >> shift) & 0xff; message = message + CharToStr( c ); } return( message ); }
Inserted Code
CopyToBuffer( orderMessage ); result = WriteFile( PipeHandle, Buffer, BufferSize, numOfBytes, 0 ); void CopyToBuffer( string message ) { for ( int i = 0; i < 64; i++ ) Buffer[i] = 0; for ( i = 0; i < StringLen( message ); i++ ) { int off = i % 4; int shift = 0; if ( off == 1 ) shift = 8; else if ( off == 2 ) shift = 16; else if ( off == 3 ) shift = 24; Buffer[i/4] |= StringGetChar( message, i ) << shift; } }