CGI на C++
С++ является гибким языком программирования, используемым для создания программ многократного использования. Как вы увидите, написание скриптов на С++ является более замысловатой задачей, чем написание обычных С++ - программ. Однако после того, как вы познакомитесь с некоторыми приемами написание CGI - скриптов на С++, вы сможете писать код, который затем будете использовать с легкостью снова и снова.
Вы создадите С++ - скрипт, названный CExsample2.CPP, который использует HTTP POST - метод для посылки информации, вводимой пользователем в форму. Для того, чтобы запустить этот скрипт, используйте элементы HTML.
Функция InitInstansce
Функцией 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 освобождается память, которая была до этого зарезервирована для окон. Следующий код реализует функцию ExitInstance:
Код:
int CExample2App::ExitInstance()
{
if (m_pView) // Clean up
delete m_pView;
if (m_pFrame)
delete m_pFrame;
return 0;
}
Как можно видеть, функция просто освобождает память в "куче", которую программа до того зарезервировала для окон.
Функция ParseCmdLine
Функция ParseCmdLine использует две переменные целого типа nCmdPos и nWordPos для того, чтобы анализировать командную строку. Переменная nCmdPos используется для пошаговой обработки командной строки при нахождении начала команды. Функция сохраняет каждую команду как OutputFile.
Функция ParseIniFile
Программа использует функцию 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
Программа использует функцию 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 назад серверу.