Форум » [x]Harbour » Помогите советом начинающему... » Ответить

Помогите советом начинающему...

Urri: Тут вот надумал переползти на xHarbour. Возникла следующая проблема: имена всех функций и подпрограмм дополняются префиксом HB_FUN_. А можно ли этого избежать так, чтобы остались родные, начальные имена. У меня весь софт построен на скриптах, в которых уже стоят вызовы функций и процедур по привычным, родным именам. И перелопатить везде в 5000 текстовых файлах-скриптах вызовы функций и поменять на новые - задача крайне утомительная с непонятной перспективой на успех.

Ответов - 294, стр: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 All

Петр: Pasha пишет: вызов hb_adsOemToAnsi Нужен вызов или нет - это еще вопрос, а если все жестко зашито в исходники и исходники в кодировке OEM? И простой заменой char * pucStmt = hb_adsOemToAnsi( hb_parc( 1 ), hb_parclen( 1 ) ); на char * pucStmt = hb_parc( 1 ); тоже не надо ограничиваться. Если менять, то уже как надо #ifdef ADS_USE_OEM_TRANSLATION char * pucStmt = ( hb_ads_bOEM ) ? hb_adsOemToAnsi( hb_parc( 1 ), hb_parclen( 1 ) : hb_parc(1) ); else char * pucStmt = hb_parc(1); #endif .. .. #ifdef ADS_USE_OEM_TRANSLATION if(pucStmt) hb_adsOemAnsiFree(pucStmt); #endif и так по всему adsfunc.c

Urri: Проверил. Если сделать ADSConnect и ADSCreateSQLStatement, то AdsPrepareSQL и AdsVerifySql с подставленным SQL запросом с русскими символами в строковых константах выдают .t. Так наверное и должно быть на этом этапе работы с SQL запросом. Ведь и в том примере, который у меня не работал, ошибка не возникала, просто ничего не отбирала. А в исходниках этих ф-ций такая же перекодировка стоит, как и для ADSEXECUTESQLDIRECT. Наверное для единообразия нужно и в этих ф-циях убрать эту самую перекодировку, т.к. сомнительно, чтобы разработчики rdd_sql считали, что ADS по-разному обрабатывает кодировки в каждой из этих ф-ций. Еще такой вопрос. Вызываю указанные ранее 4 ф-ции первый раз - последние две дают .t. Второй и последующие разы - дают .f. Неясно, почему так. Вызываю ADSDisconnect() - не помогает. А что нужно вызывать, чтобы каждый раз был положительный результат у ADSVerify и ADSPrepareSQL. И еще вопрос. Стало как-то нестабильно работать программа. После моего заработавшего запроса я вызываю DBEDIT() без параметров, без наворотов, просто чтобы посмотреть что получилось. После нажатия ESC в DBEDIT программа вываливается с дикими виндовыми ошибками и просит извинить за неудобства. Причем на какой-то непредсказуемый раз позволяет несколько раз выполнить запрос, войти-выйти из DBEDIT() и опять таки поломаться. Что бы это значило? А то меня такая нестабильность удивляет и пугает, а пользователи просто орать благим матом будут.

Urri: Добрый день, уважаемые. Замучал я всех xHarbour'ом. Работает нестабильно с SQL запросами (см.предыдущее письмо) и медленно, по сравнению с Клиппером, на w98 (даже и непонятно почему... Или так и должно быть?), на сетевой принтер команда set printer to lpt2 не работает. Переполз на Harbour. Удивительно, что некоторые куски программ перестали работать (хотя в xHarbour запустились, имелись свои удивительные неожиданности, связанные с промежуточным С). Но тут вот новая-старая проблема: невозможно прочитать состояние клавиатуры... kbdstat() и hb_gtInfo(GTI_KBDSHIFTS) выдают значение 128 и на нажатие CTRL/ALT/SHIFT не реагируют. Причем как-то удивительно: если после вызова i=kbdstat() вызвать j=getkeyboardstate(), то в i что-то изменяется (и даже в соответствии с описанием), если вызов j=getkeyboardstate() убрать - снова kbdstat() возвращает 128. Что бы это значило? Я такого поведения программы совсем не понимаю. И как с этим бороться? Не оставьте без внимания мои трудности, сколько уже преодолено с помощью знатоков...


AL: Urri пишет: Переполз на Harbour. Urri, открой новую тему начинающего с Harbour. Невозможно читать все 13 стр.

Andrey: Urri пишет: на сетевой принтер команда set printer to lpt2 не работает. Переделай вывод на печать.... Здесь на форуме уже обсуждались эти проблемы, ищи и читай.... Urri пишет: Замучал я всех xHarbour'ом Пиши какая версия !

Urri: Andrey пишет: Пиши какая версия ! xHarbour Compiler build 1.2.1 (SimpLex) (Rev. 6406) Сам же ссылку мне и давал при каком-то обсуждении (по поводу совместной работы клиппера и фокспро с .CDX индексами) Andrey пишет: Переделай вывод на печать.... Здесь на форуме уже обсуждались эти проблемы, ищи и читай.... Затрахался я уже переделывать. Ни одной приличной ф-ции нету, все какие-то калечные, написанные "для совместимости"... А для нормальной работы - ничего нет. Последних 15 лет у меня вывод на печать прекрасно работал через прерывание FT_INT86, но эта ф-ция в xHarbour (и похоже в Harbour) не работает, а также FT_PEEK для работы с клавиатурой. Извини, крик души...

Andrey: Urri пишет: Затрахался я уже переделывать. И не только ты один .... но такая работа программиста....

alkresin: Urri пишет: Еще такой вопрос. Вызываю указанные ранее 4 ф-ции первый раз - последние две дают .t. Второй и последующие разы - дают .f. Неясно, почему так. Вызываю ADSDisconnect() - не помогает. А что нужно вызывать, чтобы каждый раз был положительный результат у ADSVerify и ADSPrepareSQL. И еще вопрос. Стало как-то нестабильно работать программа. После моего заработавшего запроса я вызываю DBEDIT() без параметров, без наворотов, просто чтобы посмотреть что получилось. После нажатия ESC в DBEDIT программа вываливается с дикими виндовыми ошибками и просит извинить за неудобства. Причем на какой-то непредсказуемый раз позволяет несколько раз выполнить запрос, войти-выйти из DBEDIT() и опять таки поломаться. Что бы это значило? А то меня такая нестабильность удивляет и пугает, а пользователи просто орать благим матом будут. Подготовьте 2 самодостаточных ( чтобы не надо было ничего дописывать и dbf создавать ) примера, которые демонстрируют указанные проблемы, тогда можно будет что-то обсуждать.

Urri: Вот программа самодостаточная: *-------------------------------------- procedure main LOCAL arr := { { "KOD","N",4,0 }, { "NAIM","C",60,0 } } public numsql:=0 REQUEST DBFCDX, DBFNTX, Ads Request HB_LANG_RU866,HB_CODEPAGE_RU866 hb_SetCodepage( "RU866" ) AdsSetCharType( 2, .t. ) ? 'curdir=',CurDir() ? AdsSetServerType( 1 ) ? 'AdsIsServerLoaded=',AdsIsServerLoaded( 'c:\' ) ? 'ADSConnect=',AdsConnect( "c:\" ) rddSetDefault( 'ADSCDX' ) dbCreate( "c:\street.dbf", arr ) use c:\street.dbf for i=1 to 100 append blank replace kod with i,naim with "Привет "+str(i,3) next dbCloseArea() select 0 use c:\street shared for i=1 to 1000 && 1 sql=[update street set naim='1'+upper(naim)] && 2 sql=[update street set naim=upper(naim)] && 3 sql=[update street set naim=']+str(i,3)+['+upper(naim)] ? i,sql inkey(100) runsql(sql,,.t.,'c:\') select street dbedit() next quit *-------------------------------------- function RunSql(cSQL,cAli,CloseSel,path) local selsql,sel:=select() select 0 selsql=select() if valtype(cAli)<>'C' numsql++ cAli='SQL'+alltrim(str(numsql)) endif if valtype(path)<>'C' path=substr(path_net,1,3) ADSConnect=ADSConnect(path) endif IF !AdsCreateSqlStatement(cAli,2) ? "Cannot create SQL statement" select(selsql) use select(sel) return -1 ENDIF IF !AdsExecuteSqlDirect(cSQL) ? "AdsExecuteSqlDirect - error" select(selsql) use select(sel) return -2 ENDIF select(selsql) if ValType(CloseSel)='L'.and.CloseSel use select(sel) endif return SelSql Вот .bat для запуска: @echo off setlocal cls md objx @del main.exe @del main.tds @del objx\main.exe @del objx\main.tds @del objx\*.obj > nul @del objx\*.c > nul @del objx\*.ppo > nul @set path=%path%;g:\rab\ @set path=%path%;G:\PROC\BCC55\Bin\ @set HB_INSTALL=g:\proc\xharbour @set HB_BIN_INSTALL=%HB_INSTALL%\bin @set HB_LIB_INSTALL=%HB_INSTALL%\lib @set HB_INC_INSTALL=%HB_INSTALL%\include @set HB_BCC_INSTALL=g:\proc\bcc55 @set HB_BCC_BIN_INSTALL=%HB_BCC_INSTALL%\bin @set HB_BCC_LIB_INSTALL=%HB_BCC_INSTALL%\lib @set HB_BCC_INC_INSTALL=%HB_BCC_INSTALL%\include %HB_BIN_INSTALL%\harbour main -n -q0 -gc -i%HB_INC_INSTALL% %HARBOURFLAGS% -oobjx\ -m /dxHarbour @set HB_LIBLIST=common.lib debug.lib vm.lib rtl.lib zlib.lib pcrepos.lib gtwin.lib lang.lib rdd.lib macro.lib pp.lib dbffpt.lib dbfntx.lib dbfcdx.lib hsx.lib hbsix.lib ct.lib tip.lib rddads.lib ace32.lib ct.lib libnf.lib codepage.lib %HB_USER_LIBS% %HB_BCC_BIN_INSTALL%\bcc32 -O2 -d -c -oobjx\main.obj %CFLAGS% -I%HB_BCC_INC_INSTALL% -I%HB_INC_INSTALL% -L%HB_BCC_LIB_INSTALL% -L%HB_LIB_INSTALL% objx\main.c %HB_LIBLIST% %HB_BCC_BIN_INSTALL%\bcc32 -O2 -d -emain %CFLAGS% -nobjx\ -I%HB_BCC_INC_INSTALL% -I%HB_INC_INSTALL% -L%HB_BCC_LIB_INSTALL% -L%HB_LIB_INSTALL% objx\main.c %HB_LIBLIST% copy objx\main.exe . main.exe %1 %2 %3 %4 %5 %6 %7 %8 %9 //F:120 //swappath:'c:\' //temppath:'c:\' endlocal Там есть мой путь на g:\proc\ ... - там у меня xHarbour и BCC находятся Проблема такая: в цикле 1000 раз вызывается один из SQL запросов. (для проверки удалите && и номер) && 1 - работает нормально && 2 - работает нормально && 3 - первый раз вызывается нормально, второй раз и последующие может работать, а может и выдать "AdsExecuteSqlDirect - error" много раз, а может в какой-то непредсказуемый раз вылететь с виндовым сообщением об обнаруженной ошибке. Хотелось получить рекомендации для устранения проблемы. А то мы очень надеялись на SQL запросы.

Urri: Кстати, проверил этот пример по Harbour - все прекрасно работает. Но при переходе на Harbour возникли другие проблемы, которые возможно прийдется героически преодолевать, а на xHarbour они уже как-то решены

alkresin: Странный у вас SQL запрос: update street set naim='1'+upper(naim) в поле naim каждый раз записывается значение, на 1 больше чем длина поля, тут все что угодно может произойти - в зависимости как ads такое переполнение обрабатывает. У меня вот на каждой итерации выдается предупреждение ( виндовое окошко выскакивает ) об ошибке и что 'data truncated' ...

Urri: Запрос конечно надуманный. Но каким бы он ни был - он синтаксически правильный. И не повод программе так себя вести. Запрос должен работать - или не работать, но постоянно. А то несколько раз сработает (причем количество раз - число случайное), но потом ломается. Или просто говорит, что видите ли "AdsExecuteSqlDirect - error", но не раньше второго вызова. А первый ему что, не такой уж и плохой? Реальные запросы у нас (у меня и моих сотрудников (не только я тестировал)) менее "странные", но поведение программы такое же нестабильное.

alkresin: Проблема не в том, что он надуманный, а в том, что он неправильный. Он, действительно, генерирует AdsExecuteSqlDirect - error в каждой итерации по той причине, что пытается записать в поле NAIM значение, превышающее длину этого поля. Попробуйте вместо вашего sql=[update street set naim=']+str(i,3)+['+upper(naim)] вот это: sql=[update street set naim=']+str(i,3)+['+left(upper(naim),50)]

Urri: Вопрос ведь не в этом конкретном запросе. И почему он первый раз не генерирует сообщение об ошибке, хотя и в первый раз он пытается записать в поле значение, превышающее его длину (хотя в Клиппере, Фоксе или MS SQL, Oracle записывается только то, что помещается и сообщений об ошибке не дает). Плохо то, что вылетает с виндовой ошибкой. Точно такой же вылет наблюдается при более "правильных" запросах типа записать 0 в числовую переменную или TRUE логическую (я попробую воспроизвести такую ситуацию). Кстати я писал, что этот же пример, запущенный под Harbour, работает с тем же LOCAL ADS совершенно без проблем. А что подскажите по поводу ф-ции FT_PEEK в Harbour? Она так же не работает, как и в xHarbour ?

alkresin: Я компилировал ваш пример как раз Harbour'ом ( xHarbour я не использую ), и у меня ошибка вылетала в каждой итерации, в т.ч. и первой - если убрать вызов dbedit(), который занимает весь экран, это будет лучше видно. Та "виндовая ошибка" - это сообщение ADS ( у меня по крайней мере ) - ADS всегда выдает такое окошко при ошибке в запросе. Вопрос ведь не в этом конкретном запросе Вы то мне дали именно этот конкретный запрос, я о нем и веду речь и утверждаю, что ADS ( а не xHarbour или Harbour ) воспринимает его как ошибочный. Других ваших запросов я не видел - возможно, и в них не все чисто. Кстати, если вы внимательно прочитаете ту "виндовую ошибку" ( сообщение ADS ), то найдете там, что именно не нравится ADS в вашем запросе. А что подскажите по поводу ф-ции FT_PEEK в Harbour? Она так же не работает, как и в xHarbour ? Наверняка не работает. Сам, правда, не проверял. Не использую, и никому не советую. Нравится нам это или нет, но во всех современных ОС прямой доступ к устройствам, памяти вне процесса и т.п. запрещен, иначе нельзя обеспечить защиту ядра ОС, корректную реализацию мультизадачности. Надо к этому привыкать - и находить другие способы реализации ваших задач.

Urri: Убрал DBEDIT(). В xHarbour: в моем варианте SQL запроса выдает сообщение "AdsExecuteSqlDirect - error", но при этом запрос выполняется (изменения в базе street происходят), но только почему-то всего 28 раз работает и вылетает с виндовс ошибкой (а перед этим еще какие-то досовские непонятки случаются). Для вашего варианта запроса сообщение "AdsExecuteSqlDirect - error" не выдает, но работает только 22 раза и снова вылет в виндовс. Что за полная неразбериха и с какого потолка возникают цифры 28 и 22 ??? В Harbour в моем варианте продолжает выдавать сообщение "AdsExecuteSqlDirect - error", но при этом запрос выполняется, в вашем работает без сообщений все 1000 раз. Похоже нужно на Harbour ориентироваться. Опять всякие засады преодолевать. По-поводу FT_PEEK не совсем согласен. Если бы была верна аргументация последней части предыдущего сообщения по поводу "современных ОС", то в исходниках библиотек Harbour для этой ф-ции и других подобных первым и единственным оператором нужно поставить что-то типа "return Nil", объявить всем, что оставлены эти ф-ции только для совместимости и борьбы с неразрешенными внешними ссылками, что все могут быть свободны "и находить другие способы реализации ваших задач" . Тогда зачем в текстах этих ф-ций написаны (кило)метры крутого С-шного осмысленного текста, который впрочем не работает по причине "обеспечения защиты ядра"... Может быть как многоопытный пользователь Harbour тогда подскажите, чем заменить такую ф-цию печати function prn_old(cText,nPort) set console off set print on do case case nPort=0 set printer to lpt1 case nPort=1 set printer to lpt1 case nPort=2 set printer to lpt2 case nPort=3 set printer to lpt3 case nPort=4 set printer to lpt4 endcase set device to print ?? cText set print off set device to screen set console on return Nil Проблема в том, что состояние готовности принтера кроме как ф-цией isprinter() проверить нечем, а она для матричных принтеров не очень хороша. Более существенная проблема: PRN_OLD не работает с сетевыми принтерами, назначенными к lpt2. Говорят, что на этом форуме уже обсуждалась эта проблема - все облазил, не нашел. Подскажите решение, пожалуйста.

Петр: Urri пишет: По-поводу FT_PEEK не совсем согласен. Если бы была верна аргументация последней части предыдущего сообщения по поводу "современных ОС", то в исходниках библиотек Harbour для этой ф-ции и других подобных первым и единственным оператором нужно поставить что-то типа "return Nil", объявить всем, что оставлены эти ф-ции только для совместимости и борьбы с неразрешенными внешними ссылками, что все могут быть свободны "и находить другие способы реализации ваших задач" . В отличие от вас Александр имеет отношение к исходникам библиотек Harbour и не вам советовать писать там типа "return Nil" или что-то другое - без вас разберутся. Вам же еще раз повторяю - из user mode, т.е. пользовательских приложений прямого доступа к hardware вы не получите, все действия только через соотв. драйвера. Хочу вам также напомнить, что Harbour Project - это a Free Open Source Software effort to build a multiplatform Clipper language compiler. Одна из поддерживаемых платформ DOS, о FreeDOS вы наверное слышали. Еще хочу вам напомнить, что Harbour уже около 10 лет и всем повторять что-то уже порядочно надоело. Програмист, если это действительно программист, должен иметь определенное представление об архитектуре OS. Тогда зачем в текстах этих ф-ций написаны (кило)метры крутого С-шного осмысленного текста, который впрочем не работает по причине "обеспечения защиты ядра"... Какие метры и километры, там по 30 строчек от силы. Также см.выше о поддержке DOS. Может быть как многоопытный пользователь Harbour тогда подскажите, чем заменить такую ф-цию печати После ваших пассажей я бы подумал, отвечать или нет, но вопрос все равно к Александру. Проблема в том, что состояние готовности принтера кроме как ф-цией isprinter() проверить нечем, а она для матричных принтеров не очень хороша. См. выше и Google в помощь.

alkresin: Проблемы с xHarbour комментировать не могу - я с ним не работал и не работаю. В Harbour в моем варианте продолжает выдавать сообщение "AdsExecuteSqlDirect - error", но при этом запрос выполняется, в вашем работает без сообщений все 1000 раз. У меня - точно так же, и такое поведение вполне нормально. Тогда зачем в текстах этих ф-ций написаны (кило)метры крутого С-шного осмысленного текста, который впрочем не работает по причине "обеспечения защиты ядра"... :) Там ( contrib/libnf/peek.c ) всего двадцать строк кода, написанного в начале 90-х и, скорее всего, не компилирующегося bcc32 ( поэтому этот файл и не включен в библиотеку ). Возможно, он компилируется и работает в версии Harbour для DOS - и такая есть, C компилятор - djgpp. Может быть как многоопытный пользователь Harbour тогда подскажите, чем заменить такую ф-цию печати Проверки готовности я в этой функции не нашел, тогда что же в ней не работает ? Функция на вид безобидная ... Вывод на сетевой принтер, назначенный на lpt2 ? По этому поводу ничего сказать не могу, я не назначаю сетевой принтер ни на lpt1, ни на lpt2.

Urri: *PRIVAT*

Andrey: Urri пишет: PRN_OLD не работает с сетевыми принтерами, назначенными к lpt2. Говорят, что на этом форуме уже обсуждалась эта проблема - все облазил, не нашел. Смотри: http://clipper.borda.ru/?1-4-0-00000427-000-0-0-1240313321 Рабочий пример с исходником: http://clan-clear-sky.ucoz.ru/Printer_Demo.rar



полная версия страницы