Работаю в BCB6, хотя, считаю, что это не принципиально, т.к. не использую VCL и RTL. Только то, что даёт винда. Даже RTL-овские функции типа malloc, memcpy, strcat и т.п. заменяю на виндовые или свои аналоги. Т.е. пользуюсь технологией описанной
здесь или
здесь. Плюс, заменители RTL-функций взял из библиотеки FAR'а
здесь.
Пример:
#include "..\FarHeaders\crt.hpp"
#include <windows.h>
#include <wininet.h>
#pragma hdrstop
void main() {
HINTERNET hInternet, hConnect, hRequest;
hInternet=InternetOpen("HTTP Agent", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if (hInternet) {
hConnect=InternetConnect(hInternet, "informer.gismeteo.ru", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 1);
if (hConnect) {
hRequest=HttpOpenRequest(hConnect, "GET", "/rss/28411.xml", NULL, NULL, NULL, INTERNET_FLAG_HYPERLINK|INTERNET_FLAG_PRAGMA_NOCACHE|INTERNET_FLAG_RELOAD|INTERNET_FLAG_IGNORE_CERT_CN_INVALID|INTERNET_FLAG_IGNORE_CERT_DATE_INVALID|INTERNET_FLAG_KEEP_CONNECTION|INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP|INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS, NULL);
if (hRequest) {
if (HttpSendRequest(hRequest, NULL, 0, NULL, 0)) {
unsigned long status=0, size=sizeof(status);
HttpQueryInfo(hRequest, HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_STATUS_CODE, &status, &size, NULL);
if (status==200) {
char buf[1024];
HANDLE f=CreateFile("resp.xml", GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
while (InternetReadFile(hRequest, buf, 1024, &size) && size>0)
WriteFile(f, buf, size, &size, NULL);
CloseHandle(f);
}
}
InternetCloseHandle(hRequest);
}
InternetCloseHandle(hConnect);
}
InternetCloseHandle(hInternet);
}
}
В итоге после отработки HTTP-запроса процесс так и остаётся висеть. В Билдере его можно снять по Ctrl-F2, в консоли по Ctrl-Break.
При этом. Если скомпилить это же самое с родными библиотеками BCB, то процесс не подвисает. Очевидно, BCB подчищает за собой какой-то мусор, но какой?..
Единственное найденное решение ExitProcess() не подходит, т.к. код может использоваться в dll.
Здравствуйте, qLost, Вы писали:
L>Работаю в BCB6, хотя, считаю, что это не принципиально, т.к. не использую VCL и RTL. Только то, что даёт винда. Даже RTL-овские функции типа malloc, memcpy, strcat и т.п. заменяю на виндовые или свои аналоги. Т.е. пользуюсь технологией описанной здесь или здесь.
offtop: ИМХО лучше работать с MSVC и пользоваться технологией описаной
здесьАвтор(ы): Виталий Брусенцев
Дата: 19.01.02
Статья посвящена вопросам оптимизации размера выполняемых модулей, генерируемых различными
компиляторами C++ (основное внимание уделено MS Visual С++). С этой целью рассматриваются особенности Библиотеки исполнения C/C++ и ее реализаций, а также процессы компиляции и компоновки приложений. Приведены практические приемы, позволяющие в ряде случаев уменьшить размер приложения до величины 3-4 килобайта.
. И компилятор качественнее, и способ... не через з.
[]
L>В итоге после отработки HTTP-запроса процесс так и остаётся висеть. В Билдере его можно снять по Ctrl-F2, в консоли по Ctrl-Break.
Проблема не в Вашем коде, а в том, что Wininet.dll (или кто-то от неё зависимый) создает долполнительный тред, который никто никак не завершает.
Что бы в этом убедиться, достаточно просто импортировать любую функцию из этой dll:
#include <windows.h>
#include <wininet.h>
void main()
{
void * volatile p = &InternetOpen;
}
L>При этом. Если скомпилить это же самое с родными библиотеками BCB, то процесс не подвисает. Очевидно, BCB подчищает за собой какой-то мусор, но какой?..
"Мусор" — это тот дополнительный поток, который чего-то ждет на объекте ядра.
L>Единственное найденное решение ExitProcess() не подходит, т.к. код может использоваться в dll.
ExitProcess, на мой взгляд, является верным решением: RTL его и вызывает. А если код используется в dll, то ExitProcess нужно делать в основном модуле.
Попробовал решить в лоб, принудительно выгрузив dll
HMODULE h = LoadLibrary("wininet");
FreeLibrary(h);
FreeLibrary(h);
не помагает.
Можно, конечно, попытаться разобраться, что это за поток и кто и зачем его создает... но это нужно долго отлаживать код виндоса
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Здравствуйте, gear nuke, Вы писали:
GN>offtop: ИМХО лучше работать с MSVC и пользоваться технологией описаной здесьАвтор(ы): Виталий Брусенцев
Дата: 19.01.02
Статья посвящена вопросам оптимизации размера выполняемых модулей, генерируемых различными
компиляторами C++ (основное внимание уделено MS Visual С++). С этой целью рассматриваются особенности Библиотеки исполнения C/C++ и ее реализаций, а также процессы компиляции и компоновки приложений. Приведены практические приемы, позволяющие в ряде случаев уменьшить размер приложения до величины 3-4 килобайта.
. И компилятор качественнее, и способ... не через з.
Нет, спасибо. Мне в данном случае нужен именно голый WinAPI. А Борланд при использовании данной технологии вообще не при чём.
GN>Проблема не в Вашем коде, а в том, что Wininet.dll (или кто-то от неё зависимый) создает долполнительный тред, который никто никак не завершает.
GN>"Мусор" — это тот дополнительный поток, который чего-то ждет на объекте ядра.
GN>ExitProcess, на мой взгляд, является верным решением: RTL его и вызывает. А если код используется в dll, то ExitProcess нужно делать в основном модуле.
GN>Можно, конечно, попытаться разобраться, что это за поток и кто и зачем его создает... но это нужно долго отлаживать код виндоса
В общем, это всё понятно и я пришёл к таким же выводам, но надеялся, что кто-то уже задавался таким же вопросом и уже нашёл в чём дело.

Буду рад, если кто-то ещё откликнется.