c++ Communication between programs

Discussion of chess software programming and technical issues.

Moderator: Ras

Edmund
Posts: 670
Joined: Mon Dec 03, 2007 3:01 pm
Location: Barcelona, Spain

Re: c++ Communication between programs

Post by Edmund »

One of my code samples, maybe it is of interest:

Code: Select all

extern struct s_engine_driver {
	char path[1024];

	HANDLE hChildStdoutRd;
	HANDLE hChildStdoutWr;
	HANDLE hChildStdinRd;
	HANDLE hChildStdinWr;

	PROCESS_INFORMATION piProcInfo;

	char buffer[1024];
} ed[2];

Code: Select all

void init_engine(int id) {

	_SECURITY_ATTRIBUTES sa;
	sa.nLength = sizeof(sa);
	sa.bInheritHandle = 1;
	sa.lpSecurityDescriptor = 0;

	STARTUPINFO siStartInfo;
	ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
	siStartInfo.cb = sizeof(STARTUPINFO); 
	siStartInfo.dwFlags |= STARTF_USESTDHANDLES;

	CreatePipe(&ed[id].hChildStdoutRd, &ed[id].hChildStdoutWr, &sa, 0);
	CreatePipe(&ed[id].hChildStdinRd, &ed[id].hChildStdinWr, &sa, 0);

	SetHandleInformation(ed[id].hChildStdoutRd, HANDLE_FLAG_INHERIT, 0);
	SetHandleInformation(ed[id].hChildStdinWr, HANDLE_FLAG_INHERIT, 0);
 
	ZeroMemory( &ed[id].piProcInfo, sizeof(PROCESS_INFORMATION) );
  
	siStartInfo.hStdError = ed[id].hChildStdoutWr;
	siStartInfo.hStdOutput = ed[id].hChildStdoutWr;
	siStartInfo.hStdInput = ed[id].hChildStdinRd;

	if (!CreateProcess(ed[id].path, 0, 0, 0, 1, 0, 0, 0, &siStartInfo, &ed[id].piProcInfo)) {
		//TODO: cant create
	}
	
	engine_send(id, "uci\n");
}

Code: Select all

void engine_send(int id, char * command) {
	DWORD dwWritten; 
	WriteFile(ed[id].hChildStdinWr, command, (DWORD) strlen(command), &dwWritten, 0);
}

Code: Select all

void engine_loop(int id) {

	DWORD dw, dwRead;

	PeekNamedPipe(ed[id].hChildStdoutRd, 0, 0, 0, &dw, 0);
	if (dw) {

		char chBuf[1024];

		ReadFile(ed[id].hChildStdoutRd, chBuf, 1023, &dwRead, 0);
		dw -= dwRead;
		chBuf[dwRead] = 0;

		char * pointer = chBuf;
		
		while (1) {

			char * linebreak = strchr(pointer, '\n');
			if (linebreak) linebreak[0] = 0;

			strcat(ed[id].buffer, pointer);
			
			if (!linebreak) break;
			pointer = linebreak+1;

			if (!strncmp(ed[id].buffer, "uciok", 5)) {
...
			}
			else if (!strncmp(ed[id].buffer, "readyok", 6)) {
...
			}


			ed[id].buffer[0] = 0;

		}
	}
}
regards,
Edmund
Richard Allbert
Posts: 795
Joined: Wed Jul 19, 2006 9:58 am

Re: c++ Communication between programs

Post by Richard Allbert »

HANDLE is a pointer with no type, is this correct?

DWORD I've found in windows.h

Reading msdn's description of using pipes.... it's a little dry, to say the least!

Also, msdn seems to recommend using createnamedpipe() rather than using anonymous pipes as above.

Is the difference critical? What you have done above seems to name them anyway.

Thanks for the code

Richard