Author: Rémi Coulom
Date: 01:36:02 05/23/02
Go up one level in this thread
On May 22, 2002 at 22:04:24, martin fierz wrote:
>aloha,
>
>i have written a checkers interface called "checkerboard" which uses dll's as
>checkers engines. since this approach is limited to windows, i would like to
>change things so that engines read and write to standard input and output and
>the interface reads and writes there. hmm - i just don't know how that is
>done... can somebody give me a tip? (can be very short, what kind of function
>that might be, i can then look it up in the f*** manuals).
>
>cheers
> martin
How to do this depends on your system. If you are writing this in Windows, it is
very complicated. You can take a look at winboard, as Bob suggested. My
"wbengine" code might look simpler. I have appended my code to this message. You
can find the full source at my homepage: (that's wbengine/src/wbengine.cpp)
http://remi.coulom.free.fr/programs0046.tar.gz
(it would be two lines of code in Linux)
Rémi
////////////////////////////////////////////////////////////////////////////
// Start the child engine
////////////////////////////////////////////////////////////////////////////
void CWinboardEngine::StartChild()
{
TerminateChild();
//
// Set the bInheritHandle flag so pipe handles are inherited.
//
SECURITY_ATTRIBUTES saAttr;
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = 0;
//
// Redirect child process's STDOUT:
//
HANDLE hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);
{
HANDLE hChildStdoutRd;
CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0);
SetStdHandle(STD_OUTPUT_HANDLE, hChildStdoutWr);
DuplicateHandle(GetCurrentProcess(),
hChildStdoutRd,
GetCurrentProcess(),
&hChildStdoutRdDup ,
0,
FALSE,
DUPLICATE_SAME_ACCESS);
CloseHandle(hChildStdoutRd);
}
//
// Redirect child process's STDIN:
//
HANDLE hSaveStdin = GetStdHandle(STD_INPUT_HANDLE);
{
HANDLE hChildStdinWr;
CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0);
SetStdHandle(STD_INPUT_HANDLE, hChildStdinRd);
DuplicateHandle(GetCurrentProcess(),
hChildStdinWr,
GetCurrentProcess(),
&hChildStdinWrDup,
0,
FALSE,
DUPLICATE_SAME_ACCESS);
CloseHandle(hChildStdinWr);
}
//
// Now create the child process.
//
{
STARTUPINFO siStartInfo;
ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
siStartInfo.cb = sizeof(STARTUPINFO);
fHasChild = CreateProcess(0,
(char *)sCommandLine.c_str(), //???
0,
0,
TRUE,
0,
0,
sDirectory.c_str(),
&siStartInfo,
&piProcInfo);
}
//
// After process creation, restore the saved STDIN and STDOUT.
//
SetStdHandle(STD_INPUT_HANDLE, hSaveStdin);
SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout);
if (fHasChild) {
//
// Engine initialization
//
SendToChild("xboard\n");
SetPosition(GetPosition());
//
// Create the reader thread
//
ResetEvent(hLineProcessed);
ResetEvent(hLineRead);
fStopThread = 0;
hThread = CreateThread(0, 0, ReaderThread, this, 0, &dwThread);
if (!hThread)
TerminateChild();
}
}
////////////////////////////////////////////////////////////////////////////
// Close the reader thread and terminate the child engine
////////////////////////////////////////////////////////////////////////////
void CWinboardEngine::TerminateChild()
{
if (fHasChild)
{
SendToChild("quit\n");
CloseHandle(hChildStdinRd);
CloseHandle(hChildStdoutWr);
}
if (hThread)
{
fStopThread = 1;
SetEvent(hLineProcessed);
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
dwThread = 0;
}
if (fHasChild)
{
CloseHandle(hChildStdinWrDup);
CloseHandle(hChildStdoutRdDup);
TerminateProcess(piProcInfo.hProcess, 0);
fHasChild = 0;
}
}
////////////////////////////////////////////////////////////////////////////
// Send command to child
////////////////////////////////////////////////////////////////////////////
void CWinboardEngine::SendToChild(const char *psz)
{
DWORD dwWritten;
WriteFile(hChildStdinWrDup, psz, strlen(psz), &dwWritten, 0);
InfoGeneral("<");
InfoGeneral(psz);
}
This page took 0 seconds to execute
Last modified: Thu, 15 Apr 21 08:11:13 -0700
Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.