Автор | Сообщение |
|
| |
Пост N: 86
Зарегистрирован: 08.07.06
|
|
Отправлено: 11.08.13 18:47. Заголовок: Перехожу с Clipper 5.2e на Harbour, список вопросов от "новичка"
Добрый день, уважаемые коллеги. Большое спасибо за море справочной информации по переходу, но нужно ещё пнуть меня в нужном направлении. Итак, установил Harbour 3.0 + BCC 5.5.1 ==>> 3.2.0 +minGW скомпилировал и запустил традиционный "Hello, world!" Дело перешло к проекту, из-за которого собственно и речь. Компилируется что через hbmk2, что самим харбором - без ошибок, всего с парой предупреждений, что меня немало удивило. Возникли ошибки на этапе линковки: Скрытый текст Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland Error: Unresolved external '_HB_FUN_ENVPARAM' referenced from D:\HB\TRADE100.OBJ Error: Unresolved external '_HB_FUN_INKEYTRAP' referenced from D:\HB\TRADE226.OBJ Error: Unresolved external '_HB_FUN_DISKFREE' referenced from D:\HB\TRADE222.OBJ Error: Unresolved external '_HB_FUN_DISKTOTAL' referenced from D:\HB\TRADE222.OBJ Error: Unresolved external '_HB_FUN_BIOSDATE' referenced from D:\HB\TRADE.OBJ Error: Unresolved external '_HB_FUN_FT_ONTICK' referenced from D:\HB\TRADE.OBJ Error: Unresolved external '_HB_FUN_FT_ONIDLE' referenced from D:\HB\TRADE200.OBJ Error: Unresolved external '_HB_FUN_FT_IAMIDLE' referenced from D:\HB\TRADE200.OBJ Error: Unresolved external '_HB_FUN_TRAPANYKEY' referenced from D:\HB\TRADE200.OBJ Error: Unresolved external '_HB_FUN_KEYSEND' referenced from D:\HB\TRADE200.OBJ 1) Так понимаю, это ошибки из-за того, что не находятся некоторые функции из активно используемых CT3/Nanforum Toolkit ? Что делать с ними ? Отказываться ? Или есть заменители ? Error: Unresolved external '_HB_FUN_STACKFREE' referenced from D:\HB\TRADE200.OBJ Error: Unresolved external '_HB_FUN_BLILOCUSE' referenced from D:\HB\TRADE200.OBJ Error: Unresolved external '_HB_FUN_BLILOCAVL' referenced from D:\HB\TRADE200.OBJ Error: Unresolved external '_HB_FUN_BLILOCTOT' referenced from D:\HB\TRADE200.OBJ Error: Unresolved external '_HB_FUN_BLISTCUSE' referenced from D:\HB\TRADE200.OBJ Error: Unresolved external '_HB_FUN_BLISTCAVL' referenced from D:\HB\TRADE200.OBJ Error: Unresolved external '_HB_FUN_BLISTCTOT' referenced from D:\HB\TRADE200.OBJ 2) Это - ошибки из-за вызовов встроенных в Blinker функций, без них легко обойтись в принципе... Error: Unresolved external '_HB_FUN_STRNUM2ARRAY' referenced from D:\HB\TRADE208.OBJ Error: Unresolved external '_HB_FUN_CMJS_EXTRACTPARAMS' referenced from D:\HB\TRADE206.OBJ Error: Unresolved external '_HB_FUN_SELECTSTOCKS' referenced from D:\HB\TRADE220.OBJ Error: Unresolved external '_HB_FUN_APPLYSERTCHAGES' referenced from D:\HB\TRADE221.OBJ Error: Unresolved external '_HB_FUN_APPLYCARGOCHAGES' referenced from D:\HB\TRADE221.OBJ Error: Unresolved external '_HB_FUN_APPLYPRICECHAGES' referenced from D:\HB\TRADE221.OBJ 3) А вот это - самое странное - это мои функции, причем некоторые из них вызываются многократно из других модулей. Например ApplyCargoChanges является STATIC в самом модуле TRADE221 - почему линковщик ее не видит, наряду с парой Apply... других ? SelectStocks активно используется в других модулях - но там линкер почему-то ошибок не видит...
| Help, please - что делать и куды бечь ?
|
|
|
Ответов - 285
, стр:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
All
[только новые]
|
|
|
| |
Пост N: 236
Зарегистрирован: 08.07.06
|
|
Отправлено: 26.08.13 16:35. Заголовок: http://www.hmgforum...
http://www.hmgforum.com/viewtopic.php?f=5&t=2169 Походу существует какая-то фигня, из-за которой Harbour не ждет и не пытается повторить несколько раз (как Clipper ?) попытку открыть таблицу и индекс... Т.е. попытался один раз - сразу ставим юзера в известность... каким только вот образом ?
|
|
|
|
| Администратор
|
Пост N: 2957
Зарегистрирован: 23.05.05
|
|
Отправлено: 26.08.13 17:39. Заголовок: Sergy пишет: Возник..
Sergy пишет: цитата: | Возникает ошибка: Ошибка DBCMD/2001 Файл не открыт: ORDLISTADD Вызов из ORDLISTADD(0) Вызов из DBSETINDEX(0) Вызов из OPENMAIL(81) ... Судя по ошибке, dbf открылся, а ntx - нет. |
| Поясняю второй раз. Ошибка возникла при открытии индекса, вызов из dbSetIndex/OrdListAdd. Код ошибки 2001 - это EDBCMD_NOTABLE, т.е вызов из неоткрытой рабочей области. Это означает, что предыдущая команда use была неудачной. Чтобы было понятнее, вот исходник OrdListAdd из сырцов харбора: HB_FUNC( ORDLISTADD ) { AREAP pArea = ( AREAP ) hb_rddGetCurrentWorkAreaPointer(); // текущая рабочая область if( pArea ) // Проверка, открыта ли рабочая область { // Открытие индекса ... } else // не открыта, возникает ошибка 2001, здесь и только здесь hb_errRT_DBCMD( EG_NOTABLE, EDBCMD_NOTABLE, NULL, HB_ERR_FUNCNAME ); } цитата: | Вы меня совсем уж за придурка не держите плиз. больше 15 лет разработки и поддержания именно этой задачи. В сети сидят одновременно 20-30 юзеров работали на Clipper задаче. Но медленно. В EXCLUSIVE открывается локальный файл со справочником, который редко меняется (имена, цены, контрагенты). Целиком берется и целиком сливается. Дальше строится локальный индекс и открывается в ESXCLUSIVE. Первый пример (с mail.dbf) - способ открытия по умолчанию, т.е. SHARED (тк в самом начале программы установка SET EXCLUSIVE OFF). Второй - аналогичная ситуация, но файл - локальный и открывается монопольно. И не может быть открыт никаким другим процессом. Это временная таблица, которая будет стерта при выходе. Поэтому вопрос пока открыт: почему с переходом на Harbour стали возникать ошибки такого рода: Ошибка DBCMD/2001 Файл не открыт: ORDLISTADD |
| Что мешает вам вставить проверку на neterr после выполнения use ? Сразу все станет на свои места. По вашему коду не видно, в каком режиме открывается mail.dbf. Если не устанавливалось никакого нестандартного обработчика ошибок, то что клиппер, что харбор не будет генерировать исключение только в том случае, когда файл не открыт из-за ошибки доступа к нему. Насчет второго примера, когда открывается локальный файл в режиме exclusive. Возможно, на этом компьютере была запущена вторая копия программы, которая попытается открыть этот файл также монопольно, и возникнет та же ошибка. Я же ваш код не вижу, могу только сказать по логу ошибки, по какой причине она возникла. Третий раз повторять надо или ограничимся ? В теме по ссылке на hmgforum ясно видно, что файл открывается монопольно. И что непонятно ? Что хотели, то и получили. Файл уже открыт другой задачей, и не может быть открыт монопольно. А что это за фантазии насчет того, что клиппер пытается несколько раз открывать файл ?
|
|
|
|
| |
Пост N: 22
Зарегистрирован: 21.04.13
|
|
Отправлено: 26.08.13 17:41. Заголовок: EXCLUSIVE
Цитата: И не может быть открыт никаким другим процессом Этого (знать наверняка и) утверждать никак невозможно. Есть , например, Google Desktop, который при своей работе может занимать монопольно файлы DBF, NTX и прочие и легко может завалить задачу. Да и зависшие блокировки от операционки бывают да мало ли чего. В терминальном режиме можно потерять сеанс задачи, который будет жить на таблицах самостоятельно.
|
|
|
|
| |
Пост N: 237
Зарегистрирован: 08.07.06
|
|
Отправлено: 26.08.13 17:53. Заголовок: Pasha пишет: Что ме..
Pasha пишет: цитата: | Что мешает вам вставить проверку на neterr после выполнения use ? |
| Вот лог ошибки: Скрытый текст Ошибка DBCMD/2001 Файл не открыт: ORDLISTADD Вызов из ORDLISTADD(0) Вызов из DBSETINDEX(0) Вызов из IP_LOAD(734) Вызов из PRINTPRLIST(3715) ... Open Tables: 1. BUYPRICE 2. PRICE 3. RESERV 4. AMOUNT 5. AMIMAGE 6. IPRICEV
| Вот код, который работает в данном случае: Скрытый текст
area:=SELECT() IF !FileExist(local_dir+"ipricev.dbf") // нет образа локально - загружаем CheckNLoad("ipricev") // копируем с сервера в локальную папку и строим индекс CLOSE ipricev ENDI USE (local_dir+"ipricev") INDEX (local_dir+"ipricev") EXCLUSIVE NEW /// <<< строка 734 IF NETERR() /// сюда уже не попадает, программа завершила работу
| Получается, что в рабочей области N6 уже открыт dbf, но не открыт индекс... цитата: | // не открыта, возникает ошибка 2001, здесь и только здесь |
| Мда... нужно будет всерьез задуматься... Тогда каковы причины не открытия *.dbf ? Ведь он окрывается в 9 случаях из 10 нормально. И юзеры рядом работают...
|
|
|
|
| |
Пост N: 238
Зарегистрирован: 08.07.06
|
|
Отправлено: 26.08.13 17:56. Заголовок: Pasha пишет: Возмож..
Pasha пишет: цитата: | Возможно, на этом компьютере была запущена вторая копия программы, |
| Это тоже полностью исключено. Открывается в монопольном режиме mem файл с сохраненными переменными. Вторая копия за 15 лет ни разу еще не смогла начать работать в таком режиме. Выдается сообщение пользователю и привет. цитата: | А что это за фантазии насчет того, что клиппер пытается несколько раз открывать файл ? |
| Х.е. знает - посмотрел по тому примеру, дядька советует вьетнамцу попытаться несколько сек. подождать. Clipper ведь ни разу на этом месте не спотыкался. Вот и подумал...
|
|
|
|
| |
Пост N: 3469
Зарегистрирован: 17.05.05
|
|
Отправлено: 26.08.13 18:00. Заголовок: Sergy пишет: USE (l..
Sergy пишет: цитата: | USE (local_dir+"ipricev") INDEX (local_dir+"ipricev") EXCLUSIVE NEW |
| После того как поюзал эту базу локально , ты ее закрываешь ?
|
|
|
|
| Администратор
|
Пост N: 2958
Зарегистрирован: 23.05.05
|
|
Отправлено: 26.08.13 18:04. Заголовок: В этом фрагменте код..
В этом фрагменте кода ошибки нет. Но неизвестно, что в остальном коде. Возможно, файл ipricev уже был открыт в момент выдачи команды use в строке 734 Сделайте тест: use ipricev EXCLUSIVE NEW ? Alias(), NetErr() use ipricev EXCLUSIVE NEW ? Alias(), NetErr() Результат будет ожидаем: IPRICEV .T. .F. Если к команде use добавить еще опцию index, то как раз получим желаемый результат: попытка открытия индекса в неоткрытой р.о, и ошибка 2001
|
|
|
|
| |
Пост N: 239
Зарегистрирован: 08.07.06
|
|
Отправлено: 26.08.13 18:09. Заголовок: Dima пишет: После т..
Dima пишет: цитата: | После того как поюзал эту базу локально , ты ее закрываешь ? |
| Разумеется. На выходе из каждой процедуры формирования отчета идет CloseAll(), по сути обертка для CLOSE ALL и нескольких внутренних обработок.
|
|
|
|
| |
Пост N: 240
Зарегистрирован: 08.07.06
|
|
Отправлено: 26.08.13 18:10. Заголовок: Pasha пишет: В этом..
Pasha пишет: цитата: | В этом фрагменте кода ошибки нет. Но неизвестно, что в остальном коде. Возможно, файл ipricev уже был открыт в момент выдачи команды use в строке 734 Сделайте тест: use ipricev EXCLUSIVE NEW ? Alias(), NetErr() use ipricev EXCLUSIVE NEW ? Alias(), NetErr() Результат будет ожидаем: IPRICEV .T. .F. Если к команде use добавить еще опцию index, то как раз получим желаемый результат: попытка открытия индекса в неоткрытой р.о, и ошибка 2001 |
| Проблема в том, что на компе с Harbour (где база локальна) я вообще ни разу не смог получить подобные ошибки. Они возникают только в сети после перехода на Harbour. И то через раз - то есть, то нет...
|
|
|
|
| Администратор
|
Пост N: 2959
Зарегистрирован: 23.05.05
|
|
Отправлено: 26.08.13 18:21. Заголовок: Sergy пишет: Тогда ..
Sergy пишет: цитата: | Тогда каковы причины не открытия *.dbf ? Ведь он окрывается в 9 случаях из 10 нормально. И юзеры рядом работают... |
| Наиболее вероятную причину я назвал. Из текста errorsys видно: // Set NetErr() of there was a database open error IF oError:genCode == EG_OPEN .AND. ; oError:osCode == 32 .AND. ; oError:canDefault NetErr( .T. ) RETURN .F. ENDIF что NetErr( .T. ) устанавливается при ошибке открытия по команде use, когда oError:osCode == 32 32 - это Sharing violation Что такое Sharing violation думаю обьяснять не надо
|
|
|
|
| постоянный участник
|
Пост N: 239
Зарегистрирован: 17.02.12
|
|
Отправлено: 26.08.13 18:25. Заголовок: Sergy Еще с Clipper ..
Sergy Еще с Clipper делаю примерно так: bOldError := ErrorBlock( { |e|break( e ) } ) BEGIN SEQUENCE dbUseArea( .F., cRdd, cDbf, cAls, lSha ) IF ! Used() DO WHILE s-- >= 0 dbUseArea( .F., cRdd, cDbf, cAls, lSha ) IF Used(); EXIT ENDIF hb_IdleSleep(0.1) ENDDO ENDIF RECOVER USING oError lRet := .F. END SEQUENCE ErrorBlock( bOldError ) практика использования clipper, hb показала, даже на локальной базе, при больших расчетах, простое use не открывает файл handle нет - на это может влиять антивирус (особенно Касперский - это наш опыт). use в цикле - решение проблеммы
|
|
|
|
|
| постоянный участник
|
Пост N: 912
Зарегистрирован: 27.01.07
|
|
Отправлено: 26.08.13 18:28. Заголовок: Да, кстати антивирус..
Да, кстати, антивирус - реальная причина.
|
|
|
|
| |
Пост N: 3471
Зарегистрирован: 17.05.05
|
|
Отправлено: 26.08.13 18:31. Заголовок: SergKis пишет: особ..
SergKis пишет: цитата: | особенно Касперский - это наш опыт |
| а у меня (вернее у моего клиента) тоже делал NOD32 , сканировал и лочил DBF базы
|
|
|
|
| Администратор
|
Пост N: 2960
Зарегистрирован: 23.05.05
|
|
Отправлено: 26.08.13 18:37. Заголовок: В конце концов, пове..
В конце концов, поведение совеременных ОС при открытии файла в ntvdm b в реальном режиме действительно может быть различным. Я встречался с случаями, когда серверные ОС ведут себя неадекватно: файл вроде бы уже создан, а открыть его нельзя. Могут гадить и аетивирусы. И харбор тут ни при чем, и средствами харбора этот вопрос не решить. А решить его можно простыми приемами: Если используется локально временный файл, то создавать его именно как временный, и тогда его можно открывать монопольно. Во всех остальных случаях открывать файл как shared, особенно если он располагается на сетевых ресурсах Ну и вместо последовательности: use ... index ... new использовать use ... if ! neterr() set index to ...
|
|
|
|
| постоянный участник
|
Пост N: 240
Зарегистрирован: 17.02.12
|
|
Отправлено: 26.08.13 18:42. Заголовок: Pasha +1 то что use ..
Pasha +1 то что use м set index надо разделить во времени - однозначно
|
|
|
|
| |
Пост N: 241
Зарегистрирован: 08.07.06
|
|
Отправлено: 26.08.13 18:47. Заголовок: Мысли разумные и дал..
Pasha пишет: цитата: | Если используется локально временный файл, то создавать его именно как временный, и тогда его можно открывать монопольно |
| Именно так и сделано. Локальные - монопольно, удаленные - shared. В остальном - мысли разумные и дали пищу для размышлений, спасибо. Поковырялся у себя в errorsys.ch, вот что обнаружил: Скрытый текст
IF (e:genCode == EG_ZERODIV) // По умолчанию деление на ноль дает ноль RETURN (0) ENDI IF (e:SubSystem == 'DBFNTX') .AND. ; // специфика dbfntx & Win2K based servers (e:SubCode == 1035) .AND. ; (e:tries < 25) RETURN (.T.) ENDI IF (e:genCode == EG_LOCK) .AND. e:canDefault // обработка специфич.ошибки ntx в 5.2e RETURN (.F.) ENDI IF (e:genCode == EG_OPEN) .AND. (e:osCode == 32) .AND. e:canDefault // Для ошибки открытия файла в сетевом окружении..установка NETERR() // и значения SUBSYSTEM по умолчанию NetErr(.T.) RETURN (.F.) // NOTE ENDI IF (e:genCode == EG_APPENDLOCK) .AND. e:canDefault // Для ошибки блокировки во время APPEND BLANK..установка NETERR() // и значения SUBSYSTEM по умолчанию NetErr(.T.) RETURN (.F.) // NOTE END
| Откуда это могло у меня взяться - ума не приложу. То-ли это что-то из базовой поставки Clipper еще с 5.01, то-ли где-то нарыл, возможно с этого форума. У меня просто дописано сохранение сообщений, стека вызовов, открытых алиасов в report.log с последуюущим скидыванием его на сервер, чтобы можно было понять, что происходит у клиентов. Поэтому этот файл еще жив. Вопрос: что из этого лишнее и чего (возможно) не хватает ? там есть некий e:tries - может быть использовать его ?
|
|
|
|
| постоянный участник
|
Пост N: 2956
Зарегистрирован: 12.09.06
|
|
Отправлено: 26.08.13 19:14. Заголовок: Sergy пишет: Вопрос..
Sergy пишет: цитата: | Вопрос: что из этого лишнее и чего (возможно) не хватает ? |
| Выкинуть его нафиг и взять из поставки Харбора. Я писал вам, да и все тоже это скажут: Харбор более требователен к синтаксису ! Что есть очень хорошо. Харбор не отвечает за старые ошибки Клипера, он более СТАБИЛЬНЕЙ по работе в сети и локально. НЕ ТАЩИТЕ весь функционал который был на клипере, переделывайте узкие места: открытие/закрытие/блокировки баз !!! Я тоже сначала натыкался на это и злился... После переделок, со временем все становиться прозрачно и понятно !
|
|
|
|
| Администратор
|
Пост N: 2961
Зарегистрирован: 23.05.05
|
|
Отправлено: 26.08.13 19:17. Заголовок: Sergy пишет: IF (e..
Sergy пишет: цитата: | IF (e:SubSystem == 'DBFNTX') .AND. ; // специфика dbfntx & Win2K based servers (e:SubCode == 1035) .AND. ; (e:tries < 25) RETURN (.T.) ENDI |
| могу только сказать, что 1035 - это LOCKTIMEOUT
|
|
|
|
| |
Пост N: 242
Зарегистрирован: 08.07.06
|
|
Отправлено: 27.08.13 10:01. Заголовок: Сделал вот так: #..
Сделал вот так: Скрытый текст
#command USE <(db)> ; [VIA <rdd>] ; [ALIAS <a>] ; [<new: NEW>] ; [<ex: EXCLUSIVE>] ; [<sh: SHARED>] ; [<ro: READONLY>] ; [INDEX <(index1)> [, <(indexn)>]] ; ; => NetUse( ; <.new.>, <rdd>, <(db)>, <(a)>, ; if(<.sh.> .or. <.ex.>, !<.ex.>, NIL), <.ro.> ; ) ; ; [; IIF(USED(),NetSetIndex( <(index1)> ),NIL)] ; [; IIF(USED(),NetSetIndex( <(indexn)> ),NIL)] // далее: * ----------------------------------------------- * FUNC NetUse(lNew,cRdd,cDb,cAlias,lShared,lReadonly) LOCAL start_time,res,cnt cnt := 0 start_time := SECONDS() REPEAT DBUSEAREA(lNew,cRdd,cDb,cAlias,lShared,lReadonly) res:=USED() IF res EXIT ENDIF cnt++ hb_IdleSleep(0.1) UNTIL (ABS(SECONDS() - start_time) > 1) // не более 1 сек с уч.полуночи IF (cnt > 0) OutReportLog("NetUse("+cDb+") tried to open "+NTRIM(cnt)+" times and "+IIF(res,"OK","FAIL")) ENDIF RETURN res * ------------------- * FUNC NetSetIndex(cName) LOCAL start_time,res,cnt cnt := 0 start_time := SECONDS() REPEAT res:=DBSETINDEX(cName) IF res; EXIT; ENDIF hb_IdleSleep(0.1) cnt++ UNTIL (ABS(SECONDS()-start_time) > 1) // не более 1 сек c уч.перехода полуночи IF (cnt > 0) OutReportLog("NetSetIndex("+cName+") tried to open "+NTRIM(cnt)+" times and "+IIF(res,"OK","FAIL")) ENDIF RETURN res
| Получил одно вот такое сообщение: 27.08.2013 09:45:46 NetUse(caroute) tried to open 1 times and OK и несколько вот таких: Ошибка DBFNTX/1201 Файл не индексирован Вызов из DBSEEK(0) Вызов из GETNOMINALPRICE(322) Вызов из LOADDATA(148) ... Ошибка DBFNTX/1201 Файл не индексирован Вызов из DBSEEK(0) Вызов из DBVIEW(4752) Вызов из CARMANAGER(515) ... Совершенно точно вчера/позавчера и под Clipper этот код работал. В NetSetIndex() поставил проверку успешности открытия индекса ( res:=DBSETINDEX() ), но почему-то она не сработала ?
|
|
|
|
| постоянный участник
|
Пост N: 387
Зарегистрирован: 13.10.05
|
|
Отправлено: 27.08.13 12:48. Заголовок: Из моего опыта перех..
Из моего опыта перехода с Clipper на Харбор (это было уже давно- несколько лет назад). Пришлось в местах сохранения данных дописать везде Commit. Clipper и так нормально сохранял .А Харбор без этой команды, по- видимому используя буфер Windows, сбрасывал мусор в базы.
|
|
|
Ответов - 285
, стр:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
All
[только новые]
|
|