Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Передача параметров через память 
V
    Опции темы
tramp
Дата 14.4.2006, 05:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 18
Регистрация: 14.4.2006
Где: Kemerovo

Репутация: нет
Всего: нет



Здравствуй all

Дано: Есть программа-оболочка и куча модулей (exe файлов) запускаемых через нее.
Нужно передать два-три десятка параметров в модуль, в зависимости от результатов модуля.
Коммандная строка и так забита под завязку и служит для других целей.
Можно конечно организовать через временные файлы, но свопировать на диск, это по-моему дурной тон.
Через сообщения тоже как то коряво получается.
В идеале файл с всеми возможными параметрами грузится куда-нибудь в память, а модуль туда лезет и достает то, что надо.
Подскажите где копать?

PM MAIL   Вверх
chaos
Дата 14.4.2006, 07:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Серийный программист
****


Профиль
Группа: Завсегдатай
Сообщений: 2979
Регистрация: 7.7.2004
Где: Екатеринбург

Репутация: 1
Всего: 44



может помогут файлы отображаемые в память, раз не хочешь "свопировать на диск"
PM WWW   Вверх
Artemon
Дата 14.4.2006, 08:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


а ты мне нравишься
***


Профиль
Группа: Завсегдатай
Сообщений: 1771
Регистрация: 24.2.2004
Где: Челябинск

Репутация: 7
Всего: 20



Вот клиент:
Код


#include <windows.h>
//#include <windowsx.h>
#include <time.h>
#include "resource.h"

#define CLOCK_TIMER 1000

LRESULT WINAPI WndProc(HWND, UINT, WPARAM, LPARAM);

// Название клиентского приложения
char szAppName[] = "SenderTimeApp";
// Заголовок главного окна клиентского приложения
char szAppTitle[] = "Time Sender";

// Имя серверного приложения и идентификатор окна
char szServerAppName[] = "RemoteClock";
char szServerAppTitle[] = "RemoteClock";
HWND hWndServer;

char szBuf[80];
char szTerminated[]="<Terminated>";

// Идентификаторы объектов-событий, которые используются
// для синхронизации задач, принадлежащих разным процессам
HANDLE hEvent;
HANDLE hEventTermination;

// Имя объекта-события для синхронизации ввода и отображения
CHAR lpEventName[] =
     "$MyVerySpecialEventName$";

// Имя объекта-события для завершения процесса
CHAR lpEventTerminationName[] =
     "$MyVerySpecialEventTerminationName$";

// Имя отображения файла на память
CHAR lpFileShareName[] =
    "$MyVerySpecialFileShareName$";

// Идентификатор отображения файла на память
HANDLE hFileMapping;

// Указатель на отображенную область памяти
LPVOID lpFileMap;

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                     LPSTR lpCmdLine, int nCmdShow)
{
  WNDCLASSEX wc;
  HWND hWnd;
  MSG msg;

  // Преверяем, не было ли это приложение запущено ранее
  if(hWnd = FindWindow(szAppName, NULL))
  {
    // Если окно приложения было свернуто в пиктограмму,
    // восстанавливаем его
    if(IsIconic(hWnd)) ShowWindow(hWnd, SW_RESTORE);
    // Выдвигаем окно приложения на передний план
    SetForegroundWindow(hWnd);
    return FALSE;
  }

  // Ищем окно серверного приложения и сохраняем его идентификатор
  while ( (hWndServer=FindWindow(NULL,szServerAppTitle))==NULL)
    if( MessageBox(hWnd,"Сервер не найден!\nСтартовать сервер?",
                   "Info",MB_YESNO)==IDYES)
    {
       DWORD dwRetCode=(DWORD)ShellExecute(hWnd,"open",
             "..\\SERVER\\SERVER.EXE",NULL,NULL,SW_SHOWNORMAL);

       // заморозить задачу и дать возможность загрузиться серверу
       Sleep(500);

       if(dwRetCode <=32)
       {
         MessageBox(NULL," Server not found!", "Info", MB_OK);
         return FALSE;
       }
    }
    else
       return FALSE;

  // Открываем объект-событие для синхронизации отображения
  // времени на сервере
  hEvent = OpenEvent(EVENT_ALL_ACCESS, FALSE, lpEventName);
  if(hEvent == NULL)
  {
    wsprintf(szBuf,"OpenEvent: Error %ld\n",GetLastError());
    MessageBox(NULL,szBuf,"Info",MB_OK);
    return FALSE;
  }

  // Открываем объект-событие для сигнализации о
  // завершении процесса
  hEventTermination = OpenEvent(EVENT_ALL_ACCESS,
                                FALSE, lpEventTerminationName);
  if(hEventTermination == NULL)
  {
    wsprintf(szBuf,"OpenEvent (Termination): Error %ld\n", 
             GetLastError());
    MessageBox(NULL,szBuf,"Info",MB_OK);
    return FALSE;
  }

  // Открываем объект-отображение
  hFileMapping = OpenFileMapping(
    FILE_MAP_READ | FILE_MAP_WRITE, FALSE, lpFileShareName);

  // Если открыть не удалось, выводим код ошибки
  if(hFileMapping == NULL)
  {
    wsprintf(szBuf,"OpenFileMapping: Error %ld\n",
             GetLastError());
    MessageBox(NULL,szBuf,"Info",MB_OK);
    return FALSE;
  }

  // Выполняем отображение файла на память.
  // В переменную lpFileMap будет записан указатель на
  // отображаемую область памяти
  lpFileMap = MapViewOfFile(hFileMapping,
              FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);

  // Если выполнить отображение не удалось,
  // выводим код ошибки
  if(lpFileMap == 0)
  {
    wsprintf(szBuf,"MapViewOfFile: Error %ld\n", 
             GetLastError());
    MessageBox(NULL,szBuf,"Info",MB_OK);
    return FALSE;
  }

  // Регистрируем класс окна
  memset(&wc, 0, sizeof(wc));

  // Поля wc.cbSize и wc.hIconSm определены в структуре
  // WNDCLASSEX, которой можно пользоваться для
  // регистрации класса окна в Windows 95
  wc.cbSize = sizeof(WNDCLASSEX);

  // Поле wc.hIconSm задает идентификатор маленькой
  // пиктограммы, которая будет отображаться в левой
  // части заголовка окна (в области системного меню).
  // Загружаем пиктограмму из ресурсов приложения при
  // помощи функции LoadImage, так как функция
  // LoadIcon может загрузить только обычную пиктограмму
  wc.hIconSm = (HICON)LoadImage(hInstance,
    MAKEINTRESOURCE(IDI_APPICON_SM), IMAGE_ICON, 16, 16, 0);

  // Завершаем заполнение структуры WNDCLASSEX
  wc.style = 0;
  wc.lpfnWndProc = (WNDPROC)WndProc;
  wc.cbClsExtra  = 0;
  wc.cbWndExtra  = 0;
  wc.hInstance = hInstance;

  // Для загрузки обычной пиктограммы вы можете
  // использовать функцию LoadImage
  wc.hIcon =(HICON)LoadImage(hInstance,
    MAKEINTRESOURCE(IDI_APPICON), IMAGE_ICON, 32, 32, 0);

  wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
  wc.lpszMenuName = NULL;
  wc.lpszClassName = szAppName;

  // Вызываем функцию RegisterClassEx, которая выполняет
  // регистрацию окна
  if(!RegisterClassEx(&wc))

    // В случае ошибки пытаемся зарегистрировать окно
    // функцией RegisterClass
    if(!RegisterClass((LPWNDCLASS)&wc.style))
      return FALSE;

  // Создаем главное окно приложения
  hWnd = CreateWindow(szAppName, szAppTitle, WS_OVERLAPPEDWINDOW,
     CW_USEDEFAULT, CW_USEDEFAULT, 50,50, NULL, NULL, hInstance, NULL);
  if(!hWnd) return(FALSE);

  // Отображаем окно
  ShowWindow(hWnd, nCmdShow);
  UpdateWindow(hWnd);

  // Запускаем цикл обработки сообщений
  while(GetMessage(&msg, NULL, 0, 0))
  {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }
  return msg.wParam;
}

// -----------------------------------------------------
// Функция WndProc
// -----------------------------------------------------
LRESULT WINAPI
WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
  switch(msg)
  {
      case WM_CREATE:
           SetTimer(hWnd,CLOCK_TIMER,1000,NULL);
           return 0;

      case WM_TIMER :
           time_t t;
           struct tm *ltime;
           time(&t);
           ltime=localtime(&t);

           // Записываем строку в отображенную память,
           // доступную серверному процессу
           wsprintf((PSTR)lpFileMap,"%02d:%02d:%02d",
                    ltime->tm_hour,ltime->tm_min,ltime->tm_sec);

          // Устанавливаем объект-событие в отмеченное
          // состояние
          SetEvent(hEvent);
          return 0;

      case WM_DESTROY :
           // перед завершением посылаем строку серверному приложению
           // Terminated
           wsprintf((PSTR)lpFileMap,"%s","Terminated");

           // После завершения переключаем оба события
           // в отмеченное состояние для отмены ожидания в
           // процессе отображения и для завершения этого процесса
           SetEvent(hEvent);
           SetEvent(hEventTermination);

           // Закрываем идентификаторы объектов-событий
           CloseHandle(hEvent);
           CloseHandle(hEventTermination);

           // Отменяем отображение файла
           UnmapViewOfFile(lpFileMap);

           // Освобождаем идентификатор созданного
           // объекта-отображения
           CloseHandle(hFileMapping);

           KillTimer(hWnd,CLOCK_TIMER);
           PostQuitMessage (0) ;
           return 0 ;
  }
  return DefWindowProc (hWnd, msg, wParam, lParam) ;
}


Сервер:

Код

#include <windows.h>
#include "resource.h"

#define WM_WORK_CLOCK     (WM_USER + 0)

LRESULT WINAPI WndProc(HWND, UINT, WPARAM, LPARAM);

// Идентификаторы объектов-событий, которые используются
// для синхронизации задач, принадлежащих разным процессам
HANDLE hEventChar;
HANDLE hEventTermination;
HANDLE hEvents[2];

// Имя объекта-события для синхронизации ввода и отображения
CHAR lpEventName[] =
  "$MyVerySpecialEventName$";

// Имя объекта-события для завершения процесса
CHAR lpEventTerminationName[] =
  "$MyVerySpecialEventTerminationName$";

// Имя отображния файла на память
CHAR lpFileShareName[] =
  "$MyVerySpecialFileShareName$";

// Идентификатор отображения файла на память
HANDLE hFileMapping;

// Указатель на отображенную область памяти
LPVOID lpFileMap;

// Название приложения
char szAppName[] = "RemoteClock";

// Заголовок главного окна приложения
char szAppTitle[] = "RemoteClock";

// Метрики шрифта с фиксированной шириной букв
LONG cxChar, cyChar;

RECT rc;
char szBuf[80];

HINSTANCE hInst;

// -----------------------------------------------------
// Функция WinMain
// -----------------------------------------------------
int APIENTRY
WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
        LPSTR lpCmdLine, int nCmdShow)
{
  WNDCLASSEX wc;
  HWND hWnd;
  MSG msg;

  // Сохраняем идентификатор приложения
  hInst = hInstance;

  // Преверяем, не было ли это приложение запущено ранее
  if( hWnd = FindWindow(NULL, szAppTitle) )
  {
    // Если окно приложения было свернуто в пиктограмму,
    // восстанавливаем его
    if(IsIconic(hWnd)) ShowWindow(hWnd, SW_RESTORE);
    // Выдвигаем окно приложения на передний план
    SetForegroundWindow(hWnd);
    return FALSE;
  }


  // Создаем объект-событие с автоматическим сбросом в неотмеченном 
  // состоянии для синхронизации ввода и отображения, выполняемого в 
  // разных процессах
  hEventChar = CreateEvent(NULL, FALSE, FALSE, lpEventName);

  // Если произошла ошибка, получаем и отображаем ее код,
  // а затем завершаем работу приложения
  if(hEventChar == NULL)
  {
    wsprintf(szBuf,"CreateEvent: Error %ld\n",
             GetLastError());
    MessageBox(NULL,szBuf,"Info",MB_OK);
    return FALSE;
  }

/*
  // Если объект-событие с указанным именем существует,
  // считаем, что приложение EVENT уже было запущено
  if(GetLastError() == ERROR_ALREADY_EXISTS)
  {
    wsprintf(szBuf,"%s","Application SERVER already started");
    MessageBox(NULL,szBuf,"Info",MB_OK);
    return FALSE;
  }
*/

  // Создаем объект-событие для определения момента
  // завершения работы процесса ввода времени
  hEventTermination = CreateEvent(NULL,
                      FALSE, FALSE, lpEventTerminationName);

  if(hEventTermination == NULL)
  {
    wsprintf(szBuf,"CreateEvent (Termination): Error %ld\n",
             GetLastError());
    MessageBox(NULL,szBuf,"Info",MB_OK);
    return FALSE;
  }


  // Создаем объект-отображение
  hFileMapping = CreateFileMapping((HANDLE)0xFFFFFFFF,
    NULL, PAGE_READWRITE, 0, 100, lpFileShareName);

  // Если создать не удалось, выводим код ошибки
  if(hFileMapping == NULL)
  {
    wsprintf(szBuf,"CreateFileMapping: Error %ld\n",
             GetLastError());
    MessageBox(NULL,szBuf,"Info",MB_OK);
    return FALSE;
  }

  // Выполняем отображение файла на память.
  // В переменную lpFileMap будет записан указатель на
  // отображаемую область памяти
  lpFileMap = MapViewOfFile(hFileMapping,
              FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);

  // Если выполнить отображение не удалось,
  // выводим код ошибки
  if(lpFileMap == 0)
  {
    wsprintf(szBuf,"MapViewOfFile: Error %ld\n",
             GetLastError());
    MessageBox(NULL,szBuf,"Info",MB_OK);
    return FALSE;
  }

  // Готовим массив идентификаторов событий
  // для функции WaitForMultipleObjects
  hEvents[0] = hEventTermination;
  hEvents[1] = hEventChar;

  // Регистрируем класс окна
  memset(&wc, 0, sizeof(wc));
  wc.cbSize = sizeof(WNDCLASSEX);
  wc.hIconSm =(HICON) LoadImage(hInst,
    MAKEINTRESOURCE(IDI_APPICONSM),
    IMAGE_ICON, 16, 16, 0);
  wc.style = 0;
  wc.lpfnWndProc = (WNDPROC)WndProc;
  wc.cbClsExtra  = 0;
  wc.cbWndExtra  = 0;
  wc.hInstance = hInst;
  wc.hIcon = (HICON)LoadImage(hInst,
    MAKEINTRESOURCE(IDI_APPICON),
    IMAGE_ICON, 32, 32, 0);
  wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
  wc.lpszClassName = szAppName;
  if(!RegisterClassEx(&wc))
    if(!RegisterClass((LPWNDCLASS)&wc.style))
      return FALSE;

  // Создаем главное окно приложения
  hWnd = CreateWindow(szAppName, szAppTitle,
     WS_POPUPWINDOW | WS_THICKFRAME,
     100, 100, 100, 100,
     NULL, NULL, hInst, NULL);
  if(!hWnd) return(FALSE);

  // Размещаем окно в нижней левой части рабочего стола
  GetWindowRect(GetDesktopWindow(), &rc);

  MoveWindow(hWnd,
    rc.right  - cxChar * 25,
    rc.bottom - cyChar * 3,
    cxChar * 10, cyChar * 2, TRUE);

  // Отображаем окно и запускаем цикл
  // обработки сообщений
  ShowWindow(hWnd, nCmdShow);
  UpdateWindow(hWnd);
  while(GetMessage(&msg, NULL, 0, 0))
  {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }
  return msg.wParam;
}

//===================================================
//Функция WndProc
//===================================================
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
 HDC hdc;            // Индекс контекста устройства
 PAINTSTRUCT ps;     // Структура для рисования
 RECT rc;
 TEXTMETRIC tm;

 switch(msg)
 {
  case WM_CREATE:
     hdc=GetDC(hWnd);

     // Выбираем шрифт с фиксированной шириной букв
     SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));

     // Заполняем структуру информацией о метрике шрифта
     GetTextMetrics(hdc, &tm);

     // Запоминаем ширину самого широкого символа
     cxChar=tm.tmMaxCharWidth;

     // Запоминаем высоту символа с учетом межстрочного интервала
     cyChar=tm.tmHeight+tm.tmExternalLeading;

     // Выполняем инициализацию буфера szBuf, содержимое которого
     // отображается в окне приложения
     strcpy(szBuf, (LPSTR)"<Unknown>");

     ReleaseDC(hWnd, hdc);

     PostMessage(hWnd,WM_WORK_CLOCK,0,0);
     return 0;

  case WM_PAINT:
     hdc = BeginPaint(hWnd, &ps);
     GetClientRect(hWnd,&rc);
     DrawText(hdc,(PSTR)szBuf,-1,&rc, DT_CENTER |
              DT_VCENTER | DT_SINGLELINE);
     EndPaint(hWnd,&ps);

     PostMessage(hWnd,WM_WORK_CLOCK,0,0);
     return 0;

  case WM_WORK_CLOCK:
  {
       // Выполняем ожидание одного из двух событий:
       //   - завершение клиентского процесса;
       //   - завершение ввода времени
       DWORD dwRetCode = WaitForMultipleObjects(2,hEvents, FALSE, INFINITE);

       // Если ожидание любого из двух событий было отменено,
       // если произошло первое событие (завершение клиентского
       // процесса) или если произошла ошибка, прерываем цикл
       if(dwRetCode == WAIT_OBJECT_0 || dwRetCode == WAIT_FAILED)
       {
           DestroyWindow(hWnd);
           return 0;
       }

       wsprintf(szBuf,"%s",(PSTR)lpFileMap);

       // Перерисовываем содержимое окна, отображая полученную строку символов
       InvalidateRect(hWnd, NULL, TRUE);
       return 0;
  }

  case WM_DESTROY:
    // Закрываем идентификаторы объектов-событий
    CloseHandle(hEventChar);
    CloseHandle(hEventTermination);

    // Отменяем отображение файла
    UnmapViewOfFile(lpFileMap);

    // Освобождаем идентификатор созданного
    // объекта-отображения
    CloseHandle(hFileMapping);

    PostQuitMessage(0);
    return 0;

  default:
      return(DefWindowProc(hWnd, msg, wParam, lParam));
  }
}






--------------------
Контроль топлива на топливозаправщиках, мониторинг автотранспорта, расчет зарплаты водителей www.rscat.ru
PM MAIL   Вверх
chaos
Дата 14.4.2006, 08:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Серийный программист
****


Профиль
Группа: Завсегдатай
Сообщений: 2979
Регистрация: 7.7.2004
Где: Екатеринбург

Репутация: 1
Всего: 44



и нафига мне столько кода))(я это к тому что мало кто будет разбираться в нем)
ты скажи что не получается?
да кстати можно еще слать данные в сообщении WM_COPYDATA

PM WWW   Вверх
tramp
Дата 14.4.2006, 09:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 18
Регистрация: 14.4.2006
Где: Kemerovo

Репутация: нет
Всего: нет



to chaos
Цитата

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


Вот это я и имел ввиду. Можно чуть поподробнее?

И нельзя ли обойтись без сервера-клиента?

Допустим кинули файл в память, знаем адрес, передаем адрес в параметрах модуля, читаем адрес?


Это сообщение отредактировал(а) tramp - 14.4.2006, 09:24
PM MAIL   Вверх
pandrew
Дата 14.4.2006, 10:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 213
Регистрация: 27.3.2006

Репутация: 3
Всего: 3



Цитата(tramp @ 14.4.2006, 09:14)
И нельзя ли обойтись без сервера-клиента?
Допустим кинули файл в память, знаем адрес, передаем адрес в параметрах модуля, читаем адрес?

ИМХО разумнее не выдумывать новые способы обмена информацией, а взять готовые решения. Сегодня тебе кажется, что достаточно связи один ко многим, завтра клиентам захочется извещать оболочку о ходе работ, о результатах.
Т.о. разумнее один раз сляпать COM-сервер с поддержкой событий (примеров полно, и при некотором опыте делается за полчаса) и иметь полноценный обмен любой информацией.
PM MAIL   Вверх
maxim1000
Дата 14.4.2006, 11:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: нет
Всего: 110



Цитата(tramp @ 14.4.2006, 08:14 Найти цитируемый пост)
Допустим кинули файл в память, знаем адрес, передаем адрес в параметрах модуля, читаем адрес?

ну с адресом - это уж слишком: у разных процессов разные адресные пространства
проще работать с именованными объектами
например, сделать именованный файл, отображаемый в памяти
передающая программа создает его с каким-нибудь именем (аналог адреса)
принимающая открывает (должна знать это имя)
Цитата(tramp @ 14.4.2006, 08:14 Найти цитируемый пост)
Вот это я и имел ввиду. Можно чуть поподробнее?

MSDN, поиск по слову CreateFileMapping, там есть ссылка на пример...

если хочется рассмотреть другие варианты - можно почитать о pipes, mailslots
хотя ИМХО mapped files тут подходят...


--------------------
qqq
PM WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C++ Builder | Следующая тема »


 




[ Время генерации скрипта: 0.0697 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.