Communication between MetaTraders - Is it possible without read/write files? [B600+]

 

Dear Coders,

Is it possible to make a communication between two (or more) MetaTraders without files?

I have a technique with Named Pipes. But it does not work since Build 600. There are some topics about Named Pipes & B600+, but I can not find a good solution to make it well-functioning.

I tried to use the Named Pipes in a DLL file with Visual Studio C++. But when my DLL try to run the CreateNamedPipe function, I get this MetaTrader error message:

'Access violation read to 0x775145F4 in 'C:\_\Projects\Cubic8\Debug\myVisualCNamedPipe_v601.dll'

C++ function:

MT4_EXPFUNC int __stdcall NamedPipeInit(const int id){
        if (license < 1){
                // License check failed
                return(-1);
        }
        else{
                // Create a pipe to send data
                HANDLE pipe = CreateNamedPipe(
                        L"\\\\.\\pipe\\fxcSkype-"+id,   // name of the pipe
                        PIPE_ACCESS_OUTBOUND,           // 1-way pipe -- send only
                        //PIPE_ACCESS_DUPLEX,           // 2-way pipe - send & receive
                        PIPE_TYPE_BYTE,                 // send data as a byte stream
                        1,                              // only allow 1 instance of this pipe
                        0,                              // no outbound buffer
                        0,                              // no inbound buffer
                        0,                              // use default wait time
                        NULL                            // use default security attributes
                        );
                if (pipe == NULL || pipe == INVALID_HANDLE_VALUE) {
                        // Failed to create outbound pipe instance.
                        // look up error code here using GetLastError()
                        return(-2);
                }
                // Waiting for a client to connect to the pipe...
                // This call blocks until a client process connects to the pipe
                BOOL result = ConnectNamedPipe(pipe, NULL);
                if (!result) {
                        // Failed to make connection on named pipe.
                        // look up error code here using GetLastError()
                        CloseHandle(pipe); // close the pipe
                        return(-3);
                }
                return(1);
        }
}


What do you think about this DLL Named Pipe? It can work?

Or, do you know any other technique to communicate two MetaTraders with each other?

Thank you in advance.

Relative

 

There is an mt4-example: ..\Include\Files\FilePipe.mqh.

I would prefer Windows kernel32.dll functions:

#import "kernel32.dll" //http://msdn.microsoft.com/en-us/library/windows/desktop/aa365467%28v=vs.85%29.aspx
        int CreateNamedPipeW(string PipeName,int dwOpenMode,int dwPipeMode,int nMaxInstances,int nOutBufferSize,int nInBufferSize,int nDefaultTimeOut,int lpSecurityAttributes);
        int CreateNamedPipeA(string PipeName,int dwOpenMode,int dwPipeMode,int nMaxInstances,int nOutBufferSize,int nInBufferSize,int nDefaultTimeOut,int lpSecurityAttributes);
        int ConnectNamedPipe(int hPipe, int lpOverlapped);
        int CallNamedPipeW(string PipeName, string outBuffer, int outBufferSz, uint& inBuffer[], int inBufferSz, int& bytesRead[], int timeOut);
        int CallNamedPipeA(string PipeName, string outBuffer, int outBufferSz, uint& inBuffer[], int inBufferSz, int& bytesRead[], int timeOut);
        int ReadFile(int hPipe, int& inBuffer[],int NumberOfBytesToRead, int& bytesRead[], int lpOverlapped);
        int WriteFile(int hPipe, string sBuffer, int NumberOfBytesToWrite, int& bytesWritten[], int lpOverlapped);
        int FlushFileBuffers(int hPipe);
        int DisconnectNamedPipe(int hPipe);
        int CloseHandle(int hPipe);
#import

But be aware, the Pipe-Server can block!

 

gooly:

But be aware, the Pipe-Server can block!

How do you mean? Block? Can it work or not?
 
Relative:
How do you mean? Block? Can it work or not?

I think he means the simple synchronous mode would wait for timeout at line 

BOOL result = ConnectNamedPipe(pipe, NULL);

I have been using the asynchronous mode with the current MT4 versions, and it behaves quite safe, even in the indicators there is no block. I use pure OO programming approach, so putting the code here would not help you, sorry.

 

DeepThought:

I use pure OO programming approach, so putting the code here would not help you, sorry.

 

I don't know what can be the pure OO programming approach and why would not help me.

I think, my old Named Pipe technique was also asynchronous. It's not problem.

 
Relative:

I don't know what can be the pure OO programming approach and why would not help me.

I think, my old Named Pipe technique was also asynchronous. It's not problem.

Ok, I can try to help you by printing out the server code file content and you would see if it does have sense for you. I think one of the moderators could help you more, I do not think I am a good teacher.

#include <Custom/winapi/NamedPipe.class.mqh>

class NamedPipeServer: public NamedPipe {

public:
   NamedPipeServer(string aName): NamedPipe(aName) {}
   ~NamedPipeServer() {
      disconnect();
   }
   
   bool createServer() {   
      TRACEIN_;
      close();
      string pipeName = "\\\\.\\pipe\\" + name;
      DEBUG("Creating an instance of a named pipe... " + pipeName );
      OVERLAPPED tmp;
      // copy defaults
      overlappedStructure = tmp;
      overlappedStructure.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
       
      lastError = ERR_NO_ERROR;
       // Create a pipe to send data
      pipe = Kernel32::CreateNamedPipeW(
           pipeName, 
           PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED, 
           0, 
           255, 
           1000000, 
           1000000, 
           PIPE_TIMEOUT_CONNECT, 
           NULL 
       );
    
       bool result = (pipe != INVALID_HANDLE_VALUE);
       updateError(result);
       
       TRACEOUT(result);  
       return result;
   }
   
   bool connect() {
      TRACEIN_;
       DEBUG("Waiting for a client to connect to the pipe..." );
           
       bool result = Kernel32::ConnectNamedPipe(pipe, overlappedStructure);
       updateError(result);
                     
       TRACEOUT(result);
       return result;
   }

   bool disconnect() {
      TRACEIN_;
       Kernel32::CancelIo(pipe);
       bool result = Kernel32::DisconnectNamedPipe(pipe);
       updateError(result);
       lostConnection = false;
       
       TRACEOUT(result);
       return result;
   }
    
   void resetConnection() {
      disconnect();
      connect();
   }
   
};
 
DeepThought:

I think he means the simple synchronous mode would wait for timeout at line 

BOOL result = ConnectNamedPipe(pipe, NULL);

I have been using the asynchronous mode with the current MT4 versions, and it behaves quite safe, even in the indicators there is no block. I use pure OO programming approach, so putting the code here would not help you, sorry.

Isn't the pipe-server - as far as I remember - not only blocking while waiting for a connection but as well while waiting for the next line from the pipe-client?

So if you have an e.g. an EA with a pipe-server in OnTick() OnTick is started by an in coming tick but the execution will stop at the pipe-server until new line from the pipe-client arrives?

 
gooly:

Isn't the pipe-server - as far as I remember - not only blocking while waiting for a connection but as well while waiting for the next line from the pipe-client?

So if you have an e.g. an EA with a pipe-server in OnTick() OnTick is started by an in coming tick but the execution will stop at the pipe-server until new line from the pipe-client arrives?


 

It sounds very probably, but I have been using pipes with the FILE_FLAG_OVERLAPPED only, no intention to test the synchronous mode any more. I realized that if the synchronous mode crashed, it screwed the entire Terminal as well.

 
Thank you for your help. I'm working on it...