Перейти к содержанию

popoff

Пользователи
  • Постов

    133
  • Зарегистрирован

  • Посещение

Сообщения, опубликованные popoff

  1. эта версия лучше, чем та, которую до нё выложили? ну...в плане геймплея, в плане количества багов...

    а насчёт 1 ассассин VS 20 рыцарей... так это не так сложно должно быть...во-первых он реально рэмбо...а во вторых, в самом начале научился массово всех резать...на саладинцах(20-30 человек в толпе) итог-все лежат... =))

    а пулемёта и правда нехватает(

  2. Ага выкладывай. И сразу вопрос вперед: можно ли с помощью этой тулзы в качестве функции потока использовать виртуальную функцию класса без потери полиморфизма и со всеми вытекающими из этого приемуществами?

    проверил. да можно. динамический полиморфизм сохраняется. лишь бы функция была помечена __fastcall и была членом класса.

    щас выложу на фтп, дам ссылку. а главное - напишу как пользоваться.

  3. Инклуда MULTI 2.6

    Написано мной. Используется для быстрого руления тредами. Заточен под Builder. Тоесть использует VCL библиотеки и распараллеливает функции типов:

    void __fastcall ( __closure * )(        );
    void __fastcall ( __closure * )( void * );
    void __fastcall ( __closure * )( bool * );
    void __fastcall ( __closure * )( void *, bool * );

    Для тех кто не вкурсе - __fastcall это расширения языка, указывающее компилятору на возможность передачи параметров функции не через стек а через регистры.

    __closure - это указатель на метод класса. В отличие от предусмотренного стандартом С++ указателя на метод класса, __closure кроме самого адреса метод, хранит еще и адрес экземпляра класса и физически представляет собой структуру, состоящую из двух указателей: на экземпляр класса и на метод класса. Таким образом , __closure практически является указателем не просто метод класса, а на метод объекта (экземпляра) класса. Тоесть __closure указатель может уазывать на метод любого класса.

    Так же обеспечена синхронизация с VCL объектами. Тоесть внутри тред-функции можно безопасно обращаться к свойствам и методам VCL классов.

    В инклуде имеется класс Multi, методами которого реализуются следующие возможности:

    - Запуск функции в треде

    - Запуск функции в треде после произвольного семафора

    - Запуск функции в треде и установка произвольного семафора после окончания функции

    - Запуск последовательности функций в треде

    - Собственно прерывание всего этого

    интересует?

  4. В чем же тогда заключается гибкость? Т.е. получается С++ это красиво обернутый С? Сомневаюсь.

    С++ ИМХО настолько популярен не из-за относительно красивой "оболочки", и не наличию ООП, а какраз за счет наличия мощного механизма обобщенного программирования.

    согласен. не совсем корректно выразился. я имел ввиду, что C++ не потерял в гибкости по сравнению с C.

    Хоть C и создавался для написания операционных систем, но в итоге получился удобный язык общего назначения. такойвот глобал пурпос, так сказать. Да. Гибкость и глобал пурпос.

    и вообще, тема сложная. есть не просто C и C++, но и история вопроса. Которая начинается на заре Unix.

    C вдвое старше меня, и подозреваю, что гуй его красивше чем мой. Дак что я могу про него сказать с точки зрения истории?

  5. По поводу отличия C от C++

    они оба славятся олним и тем же - гибкостью. а классы/перегрузки/шаблоны с этой точки зрения - лишь надстройка. Для удобства и красоты.

    C, как инструмент, - это удобный карандаш, который можно хоть узлом завязать. Гибкий и ничего лишнего.

    C++ - это тот же карандаш, но со сменными стержнями, с резиночкой и кнопочкой "Вкл/Выкл".

    C# - модная ручка. прозрачная, с подсветкой и автоподогревом. Весьма отдаленно напоминает карандаш по форме и удобству.

    Pascal - стальной монолитный карандаш. Не пишет.

    Добавлено спустя 9 минут 40 секунд:

    К вопросу о велосипедах..

    Фабричный велик, конечно, новый, смазанный, проверенный и уже есть. Но своя развалюха как-то роднее.

    Да и вообще тут аналогия с веловипедом не совсем удачная. Если сдецтва не учился изобретать велосипеды, то никакой программист из тебя не получится. Будешь юзать всю жизнь STL - будешь индийским кодером) Хочешь научиться - сделай сам. А когда научишься сам, то можно не важно уже.

    Другое дело - сопровождаемость. Когда прога чужая, то понятно, что не нужно тратить время на поиск ошибок в стандартном векторе.

  6. GPSS - вот самый тяжелый язык для понимания.

    GPSS = General Purpose Simulating System = Система Симуляции Генерала Пурпоса

    Добавлено спустя 3 минуты 55 секунд:

    :) такие бальшие а 1С ненаете

    Там свой язык ... типа

    Если ПустоеЗначение(ВидЗначенияПодбора)=1 Тогда

    Возврат;

    КонецЕсли;

    СписокПараметров=СоздатьОбъект("СписокЗначений");

    СписокПараметров.ДобавитьЗначение("", "ИмяВызвавшейФормы");

    СписокПараметров.ДобавитьЗначение(ТаблицаМФ.Тип, "Тип");

    СписокПараметров.ДобавитьЗначение(ВидЗначенияПодбора,"Вид");

    СписокПараметров.ДобавитьЗначение(СписокЭлементовМФ, "Объекты");

    ТаблицаМФ.ФлВкл=2;

    ОткрытьФорму("Обработка.ПодборОбъектов#",СписокПараметров);

    но можно использовать внешние компоненты на любом языке

    Если( ПустоеЗначение( Открыть(мой_файл_ручка) ) ) Тогда

    ЁПРСТ;

    Возврат(быстро_нафик);

    Конец;

    лично я еслиб на русском программил, то с ума бы сошел. это ж пипец какое извращение. чувствовал бы себя Равшаном и Джумшутом вместе взятыми)

    но что есть то есть

  7. ВСЕ ПОНЯЛ!

    Дело в том, что в некоторых случаях, некоторые 16-битные программы под 9x, 2000 (но не NT) некорректно закрывают консоль. И ReadFile при попытке чтения возвращает ошибку и пустой буфер.

    Если вы работает под NT-family, просто вызвайте вашу программу через CMD. Т.е. используйте командную строку типа:

    cmd.exe /c myprog.exe

    В данном случае, CMD.EXE и поработает тем самым stub'ом, т.е. примет и воспроизведет консольный вывод и корректно все закроет.

    Все работает.

  8. делаю короче так:

     STARTUPINFO si;
    char buf[1024],bufin[1024];
    DWORD i2,i3;
    PROCESS_INFORMATION pi;
    SECURITY_ATTRIBUTES sa;
    HANDLE cstdin, wstdin, rstdout, cstdout;

    unsigned long __stdcall DO(void *p)
    {

    for(;
    {
    BOOL read=TRUE;
    while (read == TRUE)
    {
    memset(buf,0,1024);
    ReadFile(rstdout,buf,1024,&i2,0);
    read = (i2 == 1024);

    MainForm->DialogMemo->Lines->Add( buf );
    }
    }

    }

    //---------------------------------------------------------------------------

    AnsiString TMainForm :: make_console( AnsiString command )
    {
    AnsiString ret = "";

    sa.lpSecurityDescriptor = NULL;
    sa.nLength = sizeof(sa);
    sa.bInheritHandle = TRUE;

    ZeroMemory( &si, sizeof(si) );
    si.cb = sizeof(STARTUPINFO);
    GetStartupInfoA(&si);
    CreatePipe(&cstdin, &wstdin, &sa, 0);
    CreatePipe(&rstdout, &cstdout, &sa, 0);

    si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
    si.wShowWindow = FALSE;
    si.hStdOutput = cstdout;
    si.hStdError = cstdout;
    si.hStdInput = cstdin;

    CreateProcess( NULL, "cmd", 0, 0, TRUE, CREATE_NEW_CONSOLE, NULL,NULL,&si,π);

    CreateThread(0,0,DO,0,0,0);

    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);

    DialogMemo->Lines->Add(GetLastError());

    return ret;
    }

    все работает. текст из консоли CMD попадает в DialogMemo. но когда в CreateProcess запускаю не cmd, а, скажем bc.exe (BorlandC), то CreateProcess кажет ошибку 126(The specified module could not be found). Причем если убрать всю эту фигню с подменой потоков, то CreateProcess работает нормально и правильно даже на bc.exe.

    В чем дело? может потомуш cmd.exe 32-х разрадный, а bc.exe 16-ти?

  9.  HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup,
    hChildStdoutRd, hChildStdoutWr, hChildStdoutRdDup,
    hInputFile, hSaveStdin, hSaveStdout;

    BOOL CreateChildProcess(AnsiString command);
    unsigned long __stdcall ReadFromPipe(void*p);
    const BUFSIZE = 2048;

    AnsiString TMainForm :: make_console( AnsiString command )
    {
    AnsiString ret = "success";

    SECURITY_ATTRIBUTES saAttr;
    BOOL fSuccess;

    saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
    saAttr.bInheritHandle = TRUE;
    saAttr.lpSecurityDescriptor = NULL;

    hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);

    if (! CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
    {
    return "Stdout pipe creation failed";
    }

    if (! SetStdHandle(STD_OUTPUT_HANDLE, hChildStdoutWr))
    {
    return "Redirecting STDOUT failed";
    }

    fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd, GetCurrentProcess(), &hChildStdoutRdDup , 0, FALSE, DUPLICATE_SAME_ACCESS);
    if( !fSuccess )
    {
    return "DuplicateHandle failed";
    }
    CloseHandle(hChildStdoutRd);

    hSaveStdin = GetStdHandle(STD_INPUT_HANDLE);

    if (! CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
    {
    return "Stdin pipe creation failed";
    }

    if (! SetStdHandle(STD_INPUT_HANDLE, hChildStdinRd))
    {
    return "Redirecting Stdin failed";
    }

    fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr, GetCurrentProcess(), &hChildStdinWrDup, 0, FALSE, DUPLICATE_SAME_ACCESS);
    if (! fSuccess)
    {
    return "DuplicateHandle failed";
    }

    CloseHandle(hChildStdinWr);

    if(! CreateChildProcess( command ))
    {
    return "Create process failed";
    }

    if (! SetStdHandle(STD_INPUT_HANDLE, hSaveStdin))
    {
    return "Re-redirecting Stdin failed";
    }

    if (! SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout))
    {
    return "Re-redirecting Stdout failed";
    }

    hInputFile = hSaveStdin;

    if (hInputFile == INVALID_HANDLE_VALUE)
    {
    return "no input file";
    }

    CreateThread( 0, 0,ReadFromPipe, 0, 0, 0);

    return ret;
    }

    //---------------------------------------------------------------------------

    BOOL CreateChildProcess( AnsiString command )
    {
    PROCESS_INFORMATION piProcInfo;
    STARTUPINFO siStartInfo;

    ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
    siStartInfo.cb = sizeof(STARTUPINFO);
    siStartInfo.dwFlags = STARTF_USESHOWWINDOW; //??? ???!
    siStartInfo.wShowWindow = SW_HIDE; //??? ???!

    return CreateProcess(NULL,
    //command.c_str(), // command line
    "cmd",
    NULL, // process security attributes
    NULL, // primary thread security attributes

    TRUE, // handles are inherited
    0, // creation flags
    NULL, // use parent's environment
    NULL, // use parent's current directory
    &siStartInfo, // STARTUPINFO pointer
    &piProcInfo); // receives PROCESS_INFORMATION

    }

    //---------------------------------------------------------------------------

    unsigned long __stdcall ReadFromPipe(void*p)
    {
    DWORD dwRead, dwWritten;
    CHAR chBuf[BUFSIZE];
    HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);

    if (!CloseHandle(hChildStdoutWr))
    return 0;
    //return "Closing handle failed";

    for (;
    {
    if( !ReadFile( hChildStdoutRdDup, chBuf, BUFSIZE, &dwRead,
    NULL) || dwRead == 0) break;
    if (! WriteFile(hSaveStdout, chBuf, dwRead, &dwWritten, NULL))
    break;

    MainForm->DialogMemo->Lines->Add( chBuf );
    }

    }

  10. Классиеская модель Front-End Back-End. Основные функции приложения - Back, и множество пользовательских GUI - Front. На ней построенно большенство приложений в Linux.

    Как перенаправить? Можно попробовать API функции ReadFile/WriteFile и читать из stdin/stdout (соответствущие макросы для них есть), потом вставлять в Memo.

    А вот если погуглить, то можно найти и более изящное решение ;)

    да гуглил я полночи. про переназначение ввода/вывода консоли есть, но очень мало. ссылки три всего нашел, где действительно это обсуждается. нашел 2 примера. один ваще на дельфях. переделал на С++ - не работает. второй пример работает только с cmd. там в обоих примерах пайпы какието.. я первый раз про них слышу поэтому не очень понимаю чоэт такое.

    кароч тоесть вообще можно сделать так, чтоб сохранялась полная функциональность консольного приложения такого, как TurboProlog или TurboC?

    читаю щас в справке про stdin/stdout, нашел тему Creating a Child Process with Redirected Input and Output. нашел как используется

    ReadFile(hStdin, chBuf, BUFSIZE, &dwRead, NULL);

    читаю. но всеравно пока ничо непонятно. слава богу хоть на английском справка, а то как-то раз пришлось искать ответ на французском форуме)

    Добавлено спустя 24 минуты 46 секунд:

    по справке смог сделать только это:

    #include 
    #include
    #include

    #pragma hdrstop

    #pragma argsused

    #define BUFSIZE 4096

    HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup,
    hChildStdoutRd, hChildStdoutWr, hChildStdoutRdDup,
    hInputFile, hSaveStdin, hSaveStdout;

    BOOL CreateChildProcess(VOID);
    unsigned long __stdcall WriteToPipe(VOID *p);
    unsigned long __stdcall ReadFromPipe(VOID *p);
    VOID ErrorExit(LPTSTR);
    VOID ErrMsg(LPTSTR, BOOL);

    int main(int argc, char* argv[])
    {
    SECURITY_ATTRIBUTES saAttr;
    BOOL fSuccess;

    // Set the bInheritHandle flag so pipe handles are inherited.

    saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
    saAttr.bInheritHandle = TRUE;
    saAttr.lpSecurityDescriptor = NULL;

    // The steps for redirecting child process's STDOUT:
    // 1. Save current STDOUT, to be restored later.
    // 2. Create anonymous pipe to be STDOUT for child process.
    // 3. Set STDOUT of the parent process to be write handle of
    // the pipe, so it is inherited by the child process.
    // 4. Create a noninheritable duplicate of the read handle and

    // close the inheritable read handle.

    // Save the handle to the current STDOUT.

    hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);

    // Create a pipe for the child process's STDOUT.

    if (! CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
    ErrorExit("Stdout pipe creation failed\n");

    // Set a write handle to the pipe to be STDOUT.

    if (! SetStdHandle(STD_OUTPUT_HANDLE, hChildStdoutWr))
    ErrorExit("Redirecting STDOUT failed");

    // Create noninheritable read handle and close the inheritable read
    // handle.

    fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
    GetCurrentProcess(), &hChildStdoutRdDup , 0,
    FALSE,
    DUPLICATE_SAME_ACCESS);
    if( !fSuccess )
    ErrorExit("DuplicateHandle failed");
    CloseHandle(hChildStdoutRd);

    // The steps for redirecting child process's STDIN:
    // 1. Save current STDIN, to be restored later.

    // 2. Create anonymous pipe to be STDIN for child process.
    // 3. Set STDIN of the parent to be the read handle of the
    // pipe, so it is inherited by the child process.
    // 4. Create a noninheritable duplicate of the write handle,
    // and close the inheritable write handle.

    // Save the handle to the current STDIN.

    hSaveStdin = GetStdHandle(STD_INPUT_HANDLE);

    // Create a pipe for the child process's STDIN.

    if (! CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
    ErrorExit("Stdin pipe creation failed\n");

    // Set a read handle to the pipe to be STDIN.

    if (! SetStdHandle(STD_INPUT_HANDLE, hChildStdinRd))
    ErrorExit("Redirecting Stdin failed");

    // Duplicate the write handle to the pipe so it is not inherited.

    fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
    GetCurrentProcess(), &hChildStdinWrDup, 0,
    FALSE, // not inherited

    DUPLICATE_SAME_ACCESS);
    if (! fSuccess)
    ErrorExit("DuplicateHandle failed");

    CloseHandle(hChildStdinWr);

    // Now create the child process.

    if (! CreateChildProcess())
    ErrorExit("Create process failed");

    // After process creation, restore the saved STDIN and STDOUT.

    if (! SetStdHandle(STD_INPUT_HANDLE, hSaveStdin))
    ErrorExit("Re-redirecting Stdin failed\n");

    if (! SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout))

    ErrorExit("Re-redirecting Stdout failed\n");

    // Get a handle to the parent's input file.

    if (argc > 1)
    hInputFile = CreateFile(argv[1], GENERIC_READ, 0, NULL,
    OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
    else
    hInputFile = hSaveStdin;

    if (hInputFile == INVALID_HANDLE_VALUE)
    ErrorExit("no input file\n");

    // Write to pipe that is the standard input for a child process.

    //WriteToPipe();
    CreateThread( 0, 0, WriteToPipe, 0, 0, 0 );

    // Read from pipe that is the standard output for child process.

    //ReadFromPipe();
    CreateThread( 0, 0, ReadFromPipe, 0, 0, 0 );

    return 0;
    }

    BOOL CreateChildProcess()
    {
    PROCESS_INFORMATION piProcInfo;
    STARTUPINFO siStartInfo;

    // Set up members of STARTUPINFO structure.

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

    // Create the child process.

    return CreateProcess(NULL,
    "c:\\prolog\\prolog.exe", // command line
    NULL, // process security attributes
    NULL, // primary thread security attributes

    TRUE, // handles are inherited
    0, // creation flags
    NULL, // use parent's environment
    NULL, // use parent's current directory
    &siStartInfo, // STARTUPINFO pointer
    &piProcInfo); // receives PROCESS_INFORMATION
    }

    unsigned long __stdcall WriteToPipe(void *p)
    {
    DWORD dwRead, dwWritten;
    CHAR chBuf[BUFSIZE];

    // Read from a file and write its contents to a pipe.

    for (;
    {
    if (! ReadFile(hInputFile, chBuf, BUFSIZE, &dwRead, NULL) ||

    dwRead == 0) break;
    if (! WriteFile(hChildStdinWrDup, chBuf, dwRead,
    &dwWritten, NULL)) break;
    }

    // Close the pipe handle so the child process stops reading.

    if (! CloseHandle(hChildStdinWrDup))
    ErrorExit("Close pipe failed\n");
    }

    unsigned long __stdcall ReadFromPipe(VOID *p)
    {
    DWORD dwRead, dwWritten;
    CHAR chBuf[BUFSIZE];
    HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);

    // Close the write end of the pipe before reading from the

    // read end of the pipe.

    if (!CloseHandle(hChildStdoutWr))
    ErrorExit("Closing handle failed");

    // Read output from the child process, and write to parent's STDOUT.

    for (;
    {
    if( !ReadFile( hChildStdoutRdDup, chBuf, BUFSIZE, &dwRead,
    NULL) || dwRead == 0) break;
    if (! WriteFile(hSaveStdout, chBuf, dwRead, &dwWritten, NULL))
    break;
    }
    }

    VOID ErrorExit (LPTSTR lpszMessage)
    {
    fprintf(stderr, "%s\n", lpszMessage);

    ExitProcess(0);
    }

    //---------------------------------------------------------------------------

    работает, но это ведь просто то же самое получается. просто в моей консоли открывается та же самая консольная программа. типа клон)

    как к VCL-то это дело прикрутить? там нету этого.

  11. Есть консольное приложение - TurboProlog.

    Хочу написать виндовый гуй для него. Так как отдельного комипилятора, интерпретатора TurboProlog'а нету, то думаю сделать так - использовать prolog.exe таким образом, чтобы вывод с консоли происходил, например в Memo на моей форме, а, например, по нажатию кнопки на форме, текст из Memo вставлялся в консоль, начиналась бы компияция, а результат опять из консоли в мое приложение.

    Это вообще реально?

×
×
  • Создать...