Автор | Сообщение |
|
| |
Пост N: 287
Зарегистрирован: 05.10.06
|
|
Отправлено: 24.12.20 12:25. Заголовок: передача данных между программами
Есть ли возможность передать данные другой программе в виде массива достаточно большого размера кроме как через файлы и не через сокеты ? Слышал о shared memory, есть в harbour примеры ?
|
|
|
Ответов - 18
[только новые]
|
|
|
| постоянный участник
|
Пост N: 6868
Зарегистрирован: 12.09.06
|
|
Отправлено: 24.12.20 15:17. Заголовок: MIKHAIL пишет: масс..
MIKHAIL пишет: цитата: | массива достаточно большого размера |
| Какой размер ? Может можно обойтись SendMessage() - при помощи сообщения WM_COPYDATA Смотреть пример в МиниГуи - \MiniGUI\SAMPLES\BASIC\IPC
|
|
|
|
| |
Пост N: 288
Зарегистрирован: 05.10.06
|
|
Отправлено: 24.12.20 20:57. Заголовок: Andrey пишет: Какой..
Andrey пишет: всего 200 - 500тыс элементов Я так понял можно передавать в сообщении текст или бинарные данные. Т.е. нужно преобразовать массив в json форму, затем наверное желательно упаковать и передать как бинарные данные ? Наверное все же проще через промежуточную базу...
|
|
|
|
| постоянный участник
|
Пост N: 1603
Зарегистрирован: 27.01.07
|
|
Отправлено: 24.12.20 21:04. Заголовок: MIKHAIL пишет: Наве..
MIKHAIL пишет: цитата: | Наверное все же проще через промежуточную базу... |
| Однозначно.
|
|
|
|
| постоянный участник
|
Пост N: 6869
Зарегистрирован: 12.09.06
|
|
Отправлено: 25.12.20 11:24. Заголовок: MIKHAIL пишет: Наве..
MIKHAIL пишет: цитата: | Наверное все же проще через промежуточную базу... |
| Можно и через массив в файл: HB_MemoWrit( "_Dim.log", HB_ValToExp(aDim) ) А в другой проге считать из файла: cStr := ALLTRIM( hb_MemoRead("_Dim.log") ) IF LEN(cStr) == 0 // пустой файл ELSE IF AT( "{", cStr ) > 0 .AND. AT( "}", cStr ) > 0 aDim := &cStr ELSE // строка не массив ENDIF ENDIF Кстати можно этот массив передать и через SendMessage() без преобразования в json, как обычную строку !
|
|
|
|
| |
Пост N: 289
Зарегистрирован: 05.10.06
|
|
Отправлено: 25.12.20 16:08. Заголовок: Andrey пишет: Кстат..
Andrey пишет: макрос ограничение по длине имеет... цитата: | Кстати можно этот массив передать и через SendMessage() без преобразования в json, как обычную строку ! |
| Это как ? и как из строки преобразовать можно пример ? При таком объеме данных это все медленно будет ИМХО Я думал что то вроде shared memory использовать... но если нет, то dbf все решает
|
|
|
|
| |
Пост N: 7267
Зарегистрирован: 17.05.05
|
|
Отправлено: 25.12.20 17:03. Заголовок: я юзаю для этих целе..
я юзаю для этих целей FT_SAVEARR FT_RESTARR
|
|
|
|
| постоянный участник
|
Пост N: 6870
Зарегистрирован: 12.09.06
|
|
Отправлено: 25.12.20 18:39. Заголовок: MIKHAIL пишет: макр..
MIKHAIL пишет: цитата: | макрос ограничение по длине имеет... |
| Не знаю... MIKHAIL пишет: цитата: | Это как ? и как из строки преобразовать можно пример ? |
| Примерно так: cStr := HB_ValToExp(aDim) // Transfer data to window "Server" - из \MiniGUI\SAMPLES\BASIC\IPC\demo-client.prg SendMessageData( hwnd, cStr, nID ) Как принять строку смотри demo-main.prg .... IF nMsg == WM_COPYDATA // to get data cData := GetMessageData( lParam, @nDataID ) .... cStr := cData IF LEN(cStr) == 0 // пустая строка ELSE IF AT( "{", cStr ) > 0 .AND. AT( "}", cStr ) > 0 aDim := &cStr ELSE // строка не массив ENDIF ENDIF
|
|
|
|
| постоянный участник
|
Пост N: 3556
Зарегистрирован: 17.02.12
|
|
Отправлено: 25.12.20 19:11. Заголовок: Andrey пишет Как при..
Andrey пишет цитата: | Как принять строку смотри demo-main.prg |
| Прием идет в MiniGui программе, gtvwt нет обработки сообщения WM_COPYDATA для приема, может не вижу и как добавить обработчик того сообщения не ясно. MIKHAIL пишет цитата: | При таком объеме данных это все медленно будет ИМХО |
| На сообщении WM_COPYDATA можно строить обмен командами и данными, т.е. например массив в цикле обрабатываем и по элементно сообщением передаем др. программе и ждем ответа (опять WM_COPYDATA), что данные обработаны (можем иметь код возврата обработки) и снова передаем след. элемент с ожиданием ответа и т.д. по всем элементам массива (базы). Т.е. имеем типа сервер и несколько клиентов и они общаются по WM_COPYDATA. Здесь все быстро. Насколько это надо вам, если "dbf все решает". Если, все таки, такой механизм нужен, то можно пробовать на базе примера MiniGui\Samples\Basic\MixedMode, там два окна одно hmg другое gtwvt (ваша задача) и можно в hmg часть добавить обработку wm_copydata, как писал Андрей
|
|
|
|
| |
Пост N: 290
Зарегистрирован: 05.10.06
|
|
Отправлено: 25.12.20 22:28. Заголовок: SergKis пишет: масс..
SergKis пишет: цитата: | массив в цикле обрабатываем и по элементно сообщением передаем др. программе и ждем ответа |
| Задача была подготовить данные и отдать в отдельный процесс, который независимо от основной программы отработал бы и выдал результат. Так как обработка занимает длительное время и с родительской программой может случиться все что угодно, завершение пользователем или падение по ошибке, результат будет в любом случае. Сейчас в фоновом режиме идет обработка, бывает не успевает закончить... Как решить задачу много вариантов, думал юзал кто shared memory Dima пишет: цитата: | я юзаю для этих целей FT_SAVEARR FT_RESTARR |
| где посмотреть примеры ?
|
|
|
|
| |
Пост N: 605
Зарегистрирован: 17.06.10
|
|
Отправлено: 25.12.20 22:49. Заголовок: В принимающей проге ..
В принимающей проге (А) делаем класс своего окна. Тогда из проги донора (В) PostmMssage(хендл окна А, инфа). В методе обработки событий окна проги А ловим посланное и парсим
|
|
|
|
| |
Пост N: 7268
Зарегистрирован: 17.05.05
|
|
Отправлено: 25.12.20 23:02. Заголовок: MIKHAIL core-master..
MIKHAIL core-master\contrib\hbnf\doc\en\savearr.txt
|
|
|
|
|
| |
Пост N: 7269
Зарегистрирован: 17.05.05
|
|
Отправлено: 26.12.20 08:54. Заголовок: MIKHAIL пишет: и н..
MIKHAIL пишет: А что нормальный вариант тоже , минуя файлы на диске. Можно попробовать организовать передачу массива через HBNETIO. В программе B (в отдельном потоке) организуешь работу RPC сервера через netio_mtserver() +твоя функция которая будет принимать массив и что то с ним делать. В программе A подключаемся к RPC серверу и выполняем удаленно твою функцию из программы B с передачей массива. Клиентские функции это позволяют , вот они на выбор: netio_ProcExec netio_ProcExecW netio_FuncExec
|
|
|
|
| |
Пост N: 291
Зарегистрирован: 05.10.06
|
|
Отправлено: 26.12.20 11:08. Заголовок: Dima пишет: я юзаю ..
Dima пишет: цитата: | я юзаю для этих целей FT_SAVEARR FT_RESTARR |
| пробнул, для моих задач вполне подходит, 4мб файл получается за 5 секунд сохраняет на SSD и считывает так же. Спасибо!
|
|
|
|
| |
Пост N: 1674
Зарегистрирован: 20.02.11
|
|
Отправлено: 28.12.20 19:17. Заголовок: MIKHAIL пишет: проб..
MIKHAIL пишет: цитата: | пробнул, для моих задач вполне подходит, |
| Есть два момента 1)появление файла в цикле по таймеру проверять, работает конечно, но не технично 😎 2)к файлам любят придираться антивирусы. У меня на сервере один злой живет, создашь временный и не удалить пока он его не препарирует. Имхо через сообщения окну красивее, и сразу в json. Принимающая программа этот json в hash массив преобразует и ищи уже как хочешь, можно по индексу, можно по ключу. И к структуре массива не привязан, можно передавать любое количество элементов. Есть еще один экзотический способ передачи данных. Это так называемый pipe- запись в стандартное устройство ввода/вывода процесса. По сути работа с файлами без файлов на диске. Мне этот способ не зашел, но кто знает может есть любители.
|
|
|
|
| Администратор
|
Пост N: 3993
Зарегистрирован: 23.05.05
|
|
Отправлено: 29.12.20 11:44. Заголовок: Вместо файла можно и..
Вместо файла можно использовать dbf с memo-полем Передающая программа создает запись, может отметить время создания, и пишет данные в memo Принимающая программа проверяет, есть ли свежие данные, если есть - считывает их и удаляет запись Облегчается процедура проверки наличия данных, и зря не беспокоится антивирус
|
|
|
|
| Администратор
|
Пост N: 3994
Зарегистрирован: 23.05.05
|
|
Отправлено: 29.12.20 12:00. Заголовок: да, для сохранения м..
да, для сохранения массива можно использовать вместо функций FT_SAVEARR FT_RESTARR функции hb_Serialize, hb_deserialize
|
|
|
|
| |
Пост N: 7270
Зарегистрирован: 17.05.05
|
|
Отправлено: 30.12.20 19:58. Заголовок: Pasha пишет: да, дл..
Pasha пишет: цитата: | да, для сохранения массива можно использовать вместо функций FT_SAVEARR FT_RESTARR функции hb_Serialize, hb_deserialize |
| Для кодирования и записи в файл какими то средствами да , ведь сами по себе hb_Serialize, hb_deserialize не пишут/считывают в файл/файла
|
|
|
|
| постоянный участник
|
Пост N: 3557
Зарегистрирован: 17.02.12
|
|
Отправлено: 30.12.20 23:41. Заголовок: Dima пишет ведь сами..
Dima пишет цитата: | ведь сами по себе hb_Serialize, hb_deserialize не пишут/считывают в файл/файл |
| Есть интересная особенность (json не обязателен) ... hConf[ "__signature" ] := _NETIOSRV_SIGNATURE hConf[ "__version" ] := 1 hConf[ "srv.showconn" ] := netiosrv[ _NETIOSRV_lShowConn ] hConf[ "srv.allow" ] := netiosrv[ _NETIOSRV_hAllow ] hConf[ "srv.block" ] := netiosrv[ _NETIOSRV_hBlock ] hConf[ "mgm.showconn" ] := netiomgm[ _NETIOSRV_lShowConn ] hConf[ "mgm.allow" ] := netiomgm[ _NETIOSRV_hAllow ] hConf[ "mgm.block" ] := netiomgm[ _NETIOSRV_hBlock ] RETURN hb_MemoWrit( netiosrv_ConfName(), hb_Serialize( hConf ) ) STATIC FUNCTION netiosrv_ConfLoad( netiosrv, netiomgm ) LOCAL hConf := hb_Deserialize( hb_MemoRead( netiosrv_ConfName() ) ) ...
|
|
|
|