On-line: tnsr2, гостей 0. Всего: 1 [подробнее..]
АвторСообщение





Пост N: 287
Зарегистрирован: 05.10.06
ссылка на сообщение  Отправлено: 24.12.20 12:25. Заголовок: передача данных между программами


Есть ли возможность передать данные другой программе в виде массива достаточно большого размера кроме как через файлы и не через сокеты ?
Слышал о shared memory, есть в harbour примеры ?

Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 18 [только новые]


постоянный участник




Пост N: 6868
Зарегистрирован: 12.09.06
ссылка на сообщение  Отправлено: 24.12.20 15:17. Заголовок: MIKHAIL пишет: масс..


MIKHAIL пишет:

 цитата:
массива достаточно большого размера


Какой размер ?
Может можно обойтись SendMessage() - при помощи сообщения WM_COPYDATA
Смотреть пример в МиниГуи - \MiniGUI\SAMPLES\BASIC\IPC

Спасибо: 0 
ПрофильЦитата Ответить





Пост N: 288
Зарегистрирован: 05.10.06
ссылка на сообщение  Отправлено: 24.12.20 20:57. Заголовок: Andrey пишет: Какой..


Andrey пишет:

 цитата:
Какой размер ?


всего 200 - 500тыс элементов
Я так понял можно передавать в сообщении текст или бинарные данные.
Т.е. нужно преобразовать массив в json форму, затем наверное желательно упаковать и передать как бинарные данные ?
Наверное все же проще через промежуточную базу...

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник


Пост N: 1603
Зарегистрирован: 27.01.07
ссылка на сообщение  Отправлено: 24.12.20 21:04. Заголовок: MIKHAIL пишет: Наве..


MIKHAIL пишет:

 цитата:
Наверное все же проще через промежуточную базу...


Однозначно.

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост 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, как обычную строку !

Спасибо: 0 
ПрофильЦитата Ответить





Пост N: 289
Зарегистрирован: 05.10.06
ссылка на сообщение  Отправлено: 25.12.20 16:08. Заголовок: Andrey пишет: Кстат..


Andrey пишет:

 цитата:
&cStr


макрос ограничение по длине имеет...

 цитата:
Кстати можно этот массив передать и через SendMessage() без преобразования в json, как обычную строку !


Это как ? и как из строки преобразовать можно пример ?
При таком объеме данных это все медленно будет ИМХО
Я думал что то вроде shared memory использовать... но если нет, то dbf все решает

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 7267
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 25.12.20 17:03. Заголовок: я юзаю для этих целе..


я юзаю для этих целей
FT_SAVEARR
FT_RESTARR

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост 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


Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост 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, как писал Андрей

Спасибо: 0 
ПрофильЦитата Ответить





Пост N: 290
Зарегистрирован: 05.10.06
ссылка на сообщение  Отправлено: 25.12.20 22:28. Заголовок: SergKis пишет: масс..


SergKis пишет:

 цитата:
массив в цикле обрабатываем и по элементно сообщением передаем др. программе и ждем ответа


Задача была подготовить данные и отдать в отдельный процесс, который независимо от основной программы отработал бы и выдал результат. Так как обработка занимает длительное время и с родительской программой может случиться все что угодно, завершение пользователем или падение по ошибке, результат будет в любом случае. Сейчас в фоновом режиме идет обработка, бывает не успевает закончить...
Как решить задачу много вариантов, думал юзал кто shared memory

Dima пишет:

 цитата:
я юзаю для этих целей
FT_SAVEARR
FT_RESTARR


где посмотреть примеры ?

Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 605
Зарегистрирован: 17.06.10
ссылка на сообщение  Отправлено: 25.12.20 22:49. Заголовок: В принимающей проге ..


В принимающей проге (А) делаем класс своего окна. Тогда из проги донора (В)
PostmMssage(хендл окна А, инфа). В методе обработки событий окна проги А ловим посланное и парсим

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 7268
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 25.12.20 23:02. Заголовок: MIKHAIL core-master..


MIKHAIL
core-master\contrib\hbnf\doc\en\savearr.txt

Спасибо: 1 
ПрофильЦитата Ответить
администратор




Пост 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

Спасибо: 0 
ПрофильЦитата Ответить





Пост N: 291
Зарегистрирован: 05.10.06
ссылка на сообщение  Отправлено: 26.12.20 11:08. Заголовок: Dima пишет: я юзаю ..


Dima пишет:

 цитата:
я юзаю для этих целей
FT_SAVEARR
FT_RESTARR


пробнул, для моих задач вполне подходит, 4мб файл получается за 5 секунд сохраняет на SSD и считывает так же. Спасибо!

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 1674
Зарегистрирован: 20.02.11
ссылка на сообщение  Отправлено: 28.12.20 19:17. Заголовок: MIKHAIL пишет: проб..


MIKHAIL пишет:

 цитата:
пробнул, для моих задач вполне подходит,


Есть два момента
1)появление файла в цикле по таймеру проверять, работает конечно, но не технично 😎
2)к файлам любят придираться антивирусы. У меня на сервере один злой живет, создашь временный и не удалить пока он его не препарирует.

Имхо через сообщения окну красивее, и сразу в json. Принимающая программа этот json в hash массив преобразует и ищи уже как хочешь, можно по индексу, можно по ключу. И к структуре массива не привязан, можно передавать любое количество элементов.
Есть еще один экзотический способ передачи данных. Это так называемый pipe- запись в стандартное устройство ввода/вывода процесса. По сути работа с файлами без файлов на диске. Мне этот способ не зашел, но кто знает может есть любители.

Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 3993
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 29.12.20 11:44. Заголовок: Вместо файла можно и..


Вместо файла можно использовать dbf с memo-полем
Передающая программа создает запись, может отметить время создания, и пишет данные в memo
Принимающая программа проверяет, есть ли свежие данные, если есть - считывает их и удаляет запись
Облегчается процедура проверки наличия данных, и зря не беспокоится антивирус

Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 3994
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 29.12.20 12:00. Заголовок: да, для сохранения м..


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

FT_SAVEARR
FT_RESTARR

функции hb_Serialize, hb_deserialize

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 7270
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 30.12.20 19:58. Заголовок: Pasha пишет: да, дл..


Pasha пишет:

 цитата:
да, для сохранения массива можно использовать вместо функций

FT_SAVEARR
FT_RESTARR

функции hb_Serialize, hb_deserialize


Для кодирования и записи в файл какими то средствами да , ведь сами по себе
hb_Serialize, hb_deserialize не пишут/считывают в файл/файла

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост 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() ) )
...


Спасибо: 0 
ПрофильЦитата Ответить
Ответ:
1 2 3 4 5 6 7 8 9
большой шрифт малый шрифт надстрочный подстрочный заголовок большой заголовок видео с youtube.com картинка из интернета картинка с компьютера ссылка файл с компьютера русская клавиатура транслитератор  цитата  кавычки моноширинный шрифт моноширинный шрифт горизонтальная линия отступ точка LI бегущая строка оффтопик свернутый текст

показывать это сообщение только модераторам
не делать ссылки активными
Имя, пароль:      зарегистрироваться    
Тему читают:
- участник сейчас на форуме
- участник вне форума
Все даты в формате GMT  3 час. Хитов сегодня: 33
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет