С++ является гибким языком программирования, используемым для создания программ многократного использования. Как вы увидите, написание скриптов на С++ является более замысловатой задачей, чем написание обычных С++ - программ. Однако после того, как вы познакомитесь с некоторыми приемами написание CGI - скриптов на С++, вы сможете писать код, который затем будете использовать с легкостью снова и снова.
Вы создадите С++ - скрипт, названный CExsample2.CPP, который использует HTTP POST - метод для посылки информации, вводимой пользователем в форму. Для того, чтобы запустить этот скрипт, используйте элементы HTML.
Функцией InitInstansce программа резервирует память, используемую для поддержки окон ( которые так и не появятся ). Кроме того, функция анализирует командную строку и элементы INI - файла. Следующий код реализирует функцию InitInstansce:
// The one and only
CExample2App object CExample2App theApp;
//////////////////
CExample2App initialization
BOOL
CExample2App::InitInstance() { LoadStdProfileSetting();
// Load stand INI
// file options
// START CUSTOM CODE:
Web Programming
m_pFrame = new
CMainFrame;
m_pView = new
CExample2View;
CCreateContext
newContext;
newContext.m_pNewViewClass
= NULL;
newContext.m_pNewDocTemplate
= NULL;
newContext.m_pLastView
= NULL;
newContext.m_pCurrentFrame
= NULL;
newContext.m_pCurrentDoc
= NULL;
DWORD dwStyle =
WS_OVERLAPPED;
// Make a frame with
0 (no) dimensions since
// this is a
background process
if(!m_pFrame->Create(NULL,
NULL, dwStyle, CRect(0, 0, 0), NULL, NULL, OL, &newContext))
{
return FALSE;
}
m_pMainWND =
m_pFrame;
// Make a view with 0
(no) dimensions
m_pView->Create(NULL,
NULL, WS_CHILD, CRect(0, 0, 0, 0), m_pFrame, AFX_IDW_PANE_FIRST,
&newContext);
m_pView->OnInitialUpdate();
if(m_lpCmdLine[0] !=
'\0')
{
CString sIniFile;
CString sContenFile;
CString sOutputFile;
ParseCmdLine(sIniFile,
sContenFile, sOutputFile);
ParseIniFile(sIniFile.GetBuffer(0));
CreateResponse(sOutputFile,
sIniFile);
}
PostQuitMessage(0);
return TRUE;
}
Как можно видеть, программа создает только один прикладной объект ( theApp ). Программа также перегружает виртуальную функцию InitInstansce, в которой резервируется память в "куче" для объектов Frame и View. Программа использует структуру CCreateContext для того, чтобы создать окно документа и область просмотра, поскольку она перегружает процесс создания окна. Как было сказано выше, программа устанавливает размеры окон равными нулю, что предотвращает появление этих окон на экране. Программа также создает несколько переменных CString, которые используются при выполнении операции ввода/вывода.
В функции ExitInstance освобождается память, которая была до этого зарезервирована для окон. Следующий код реализует функцию ExitInstance:
int
CExample2App::ExitInstance()
{
if (m_pView) // Clean
up
delete m_pView;
if (m_pFrame)
delete m_pFrame;
return 0;
}
Как можно видеть, функция просто освобождает память в "куче", которую программа до того зарезервировала для окон.
Функция ParseCmdLine использует две переменные целого типа nCmdPos и nWordPos для того, чтобы анализировать командную строку. Переменная nCmdPos используется для пошаговой обработки командной строки при нахождении начала команды. Функция сохраняет каждую команду как OutputFile.
Программа использует функцию ParseIniFile для того, чтобы анализировать sIniFile, созданный функцией ParseCmdLine. Функция находит строки в sIniFile и сохраняет их в переменной m_saParams, используя функцию m_saParams.add(sLine):
void
CExample2App::ParseIniFile(CString, sIniFile)
{
int nIniPos = 0;
int nBufLen;
Cstring sLine;
char lpszBuf[2048];
nBufLen =
GetPrivateProfileSection("Form Literal",
(LPSTR)lpszBuf, 2048, sIniFile.GetBuffer(0));
do {
sLine = "";
while (nIniPos <
nBufLen && lpszBuf[nIniPos] != '\0')
{
sLine +=
lpszBuf[nIniPos];
nIniPos++;
}
nIniPos++;
if (sLine !=
"") {
m_saParams.Add(sLine);
}
} while (sLinw !=
"");
}
Программа использует функцию CreateResponse для того, чтобы динамически создавать HTML - документ, который сервер использует для вывода на экран данных, введенных пользователем. Короче говоря, функция, в первую очередь, формотирует эхо данных, которые она получает со стандартного ввода stdin. Ответ функции содержит информацию HTML, необходимую для соответствия спецификации HTML 3.2:
void
CExample2App::CreateResponse(Cstring sOutputFile, CString
sIniFile)
{
. int i;
int nIndex;
CString sResponse;
CFile fOutput;
CFileStatus fStatus;
CString sCustomer;
CString sKey;
CString sVal;
// Send HTML format
sResponse =
"Content-type: text/html\r\n";
sResponse +=
"\r\n";
sResponse +=
"<!DOCTYPE HTML PUBLIC \"-//W30//DTD W3 HTML
3.2//EN\">\r\n";
sResponse +=
"<HTML>\r\n";
sResponse +=
"<HEAD>\r\n";
sResponse +=
"<TITLE>Web Programming</TITLE>\r\n";
sResponse +=
"</HEAD>\r\n";
for (i = 0; i <
m_saParams.GetSize(); i++) {
sKey.Empty();
sVal.Empty();
if((nIndex =
m_saParams[i].Find('=') != -1) {
sKey =
m_saParams[i].Left(nIndex);
sVal =
m_saParams[i].Right(m_saParams[i].GetLength() - nIndex - 1 );
}
if (sVal ==
"") {
sResponse +=
"<H1>Please enter all data </H1>\r\n";
break;
}
sCustomer +=
"<H3>";
sCustomer += sKey;
sCustomer += ":
";
sCustomer += sVal;
sCustomer +=
"</H3>\r\n";
}
if (i ==
m_saParams.GetSize()) {
sResponse +=
"<H1>Web Programming`s Reply:</H1>\r\n";
sResponse =+ sCustomer;
}
sResponse +=
"</BODY>\r\n";
sResponse +=
"</HTML>\r\n";
if
(fOutput.Open(sOutputFile.GetBuffer(0), CFile::modeCreate |
CFile::modeWrite | CFile::typeBinary)) {
fOutput.Write(sResponse.GetBuffer(0),
sResponse.GetLength());
fOutput.Close();
}
}
// END MODIFICATIONS:
Web Programming
Как можно видеть, функция просто выыполняет конкатенацию ( соединение ) строк, составляющих ее ответ, в строку sResponse. Затем она возвращает эту строку sResponse назад серверу.
При создании CGI-скриптов вы имеете возможность выбора между различными языками программирования. Коротко говоря, вы имеете возможность выбора языка программирования для написания CGI-скриптов среди тех языков, которые могут работать со стандартным вводом/выводом. Основным же языком программирования для написания CGI-скриптов, является Perl ( Practical Extraction Report Language ). Об этом вы можете прочитать здесь же, выйдя в основной раздел.