Отличие CALL и обычного вызова процедуры ?!?
Модератор: Дед Пахом
Правила форума
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
Отличие CALL и обычного вызова процедуры ?!?
Уважаемые знатоки! Прошу по-возможности оперативного ответа.
НЕ МОГУ РАЗОБРАТЬСЯ С ОШИБКОЙ! В чём отличие CALL и обычного вызова процедуры ?!?
Имеется собственная DLL и в ней среди других процедура XPROC, которая открывает окно, выбирает данные из БД в Queue, затем выгружает данные в Excel. Эта процедура для работы использует другие DLL.
Имеется два похожих приложения с вызовом ЭТОЙ процедуры из ЭТОЙ DLL . Разница в том, что в ПЕРВОМ приложении ЭТА библиотека подключена сразу в проекте и вызов процедуры осуществлён через START(XPROC, 25000), а во ВТОРОМ приложении происходит динамическая загрузка этой процедуры с помощью
START(StartXProc,25000), где:
StartXProc Procedure
Code
Call(NameOfDLL, 'XPROC@xxx', 1)
Так вот, ПЕРВОЕ приложение работает отлично. ВТОРОЕ приложение в процессе выгрузки в Excel внезапно обрывается в различных местах хода выгрузки.
Системным отладчиком установлен отладчик CLARION. При обрыве отладчик сообщает: "Unknown exception", а затем "Stack overflow" ИЛИ "память не может быть READ", а затем "Access violation".
В окне отладчика "Stack Trace" последним процессом является "Unknown", а выше одна из процедур библиотеки выгрузки в Excel (разная).
Использую C55, Legacy. Win-2k Server. MSOffice XP.
Как избавиться от ошибки во ВТОРОМ приложении
НЕ МОГУ РАЗОБРАТЬСЯ С ОШИБКОЙ! В чём отличие CALL и обычного вызова процедуры ?!?
Имеется собственная DLL и в ней среди других процедура XPROC, которая открывает окно, выбирает данные из БД в Queue, затем выгружает данные в Excel. Эта процедура для работы использует другие DLL.
Имеется два похожих приложения с вызовом ЭТОЙ процедуры из ЭТОЙ DLL . Разница в том, что в ПЕРВОМ приложении ЭТА библиотека подключена сразу в проекте и вызов процедуры осуществлён через START(XPROC, 25000), а во ВТОРОМ приложении происходит динамическая загрузка этой процедуры с помощью
START(StartXProc,25000), где:
StartXProc Procedure
Code
Call(NameOfDLL, 'XPROC@xxx', 1)
Так вот, ПЕРВОЕ приложение работает отлично. ВТОРОЕ приложение в процессе выгрузки в Excel внезапно обрывается в различных местах хода выгрузки.
Системным отладчиком установлен отладчик CLARION. При обрыве отладчик сообщает: "Unknown exception", а затем "Stack overflow" ИЛИ "память не может быть READ", а затем "Access violation".
В окне отладчика "Stack Trace" последним процессом является "Unknown", а выше одна из процедур библиотеки выгрузки в Excel (разная).
Использую C55, Legacy. Win-2k Server. MSOffice XP.
Как избавиться от ошибки во ВТОРОМ приложении
- StillZero
- Ветеран
- Сообщения: 454
- Зарегистрирован: 06 Июль 2005, 2:17
- Откуда: Хабаровск
- Контактная информация:
хзВ чём отличие CALL и обычного вызова процедуры
Как вариант: использовать LoadLibrary и GetProcAddress для динамической загрузки DLL и вызова процедуры.Call(NameOfDLL, 'XPROC@xxx', 1)
прототипы api-функций:
Код: Выделить всё
PXP:LoadLibrary(*CSTRING pszModuleFileName),UNSIGNED,PASCAL,RAW,NAME('LoadLibraryA')
PXP:FreeLibrary(UNSIGNED hModule),BYTE,PASCAL,RAW,NAME('FreeLibrary'),PROC
PXP:GetProcAddress(UNSIGNED hModule,*CSTRING pszProcName),LONG, PASCAL,RAW,NAME('GetProcAddress')
в inc-файле или в глобалах описываешь прототип твоей функции:
Код: Выделить всё
MODULE('External')
PXP:OpenThemeData(UNSIGNED hWnd, BSTRING CwStr),UNSIGNED,RAW,PASCAL,DLL(__OpenThemeData_)
END
Код: Выделить всё
__UXThemeLibrary_ LONG
szLibName CSTRING(255)
szProcName CSTRING(255)
__OpenThemeData_ LONG,STATIC,NAME('PXP:OpenThemeData')
code
szLibName = 'uxtheme.dll'
__UXThemeLibrary_ = PXP:LoadLibrary(szLibName)
szProcName = 'OpenThemeData'
__OpenThemeData_ = PXP:GetProcAddress(__UXThemeLibrary_, szProcName)
Код: Выделить всё
hTheme = PXP:OpenThemeData(0, szThemeName)
удачи
Простите, уважаемый StillZero!
Но Вы невнимательны . Я не спрашивал про аналог оператора CALL
(правда, извините, я не сказал, что это пробовано - результат тот же).
Запуск проходит во всех случаях нормально.
ВОПРОС в другом: прога ВАЛИТСЯ во время выгрузки в Excel - ТОЛЬКО если процедура запущена посредством CALL (или приведённого Вами аналогичного метода) !
Но Вы невнимательны . Я не спрашивал про аналог оператора CALL
(правда, извините, я не сказал, что это пробовано - результат тот же).
Запуск проходит во всех случаях нормально.
ВОПРОС в другом: прога ВАЛИТСЯ во время выгрузки в Excel - ТОЛЬКО если процедура запущена посредством CALL (или приведённого Вами аналогичного метода) !
Re: Отличие CALL и обычного вызова процедуры ?!?
Второе приложение запускается в том же треде, что и вызывающая процедура, а первое-в другом.Митрий писал(а):Уважаемые знатоки! Прошу по-возможности оперативного ответа.
НЕ МОГУ РАЗОБРАТЬСЯ С ОШИБКОЙ! В чём отличие CALL и обычного вызова процедуры ?!?
Имеется собственная DLL и в ней среди других процедура XPROC, которая открывает окно, выбирает данные из БД в Queue, затем выгружает данные в Excel. Эта процедура для работы использует другие DLL.
Имеется два похожих приложения с вызовом ЭТОЙ процедуры из ЭТОЙ DLL . Разница в том, что в ПЕРВОМ приложении ЭТА библиотека подключена сразу в проекте и вызов процедуры осуществлён через START(XPROC, 25000), а во ВТОРОМ приложении происходит динамическая загрузка этой процедуры с помощью
START(StartXProc,25000), где:
StartXProc Procedure
Code
Call(NameOfDLL, 'XPROC@xxx', 1)
Так вот, ПЕРВОЕ приложение работает отлично. ВТОРОЕ приложение в процессе выгрузки в Excel внезапно обрывается в различных местах хода выгрузки.
Системным отладчиком установлен отладчик CLARION. При обрыве отладчик сообщает: "Unknown exception", а затем "Stack overflow" ИЛИ "память не может быть READ", а затем "Access violation".
В окне отладчика "Stack Trace" последним процессом является "Unknown", а выше одна из процедур библиотеки выгрузки в Excel (разная).
Использую C55, Legacy. Win-2k Server. MSOffice XP.
Как избавиться от ошибки во ВТОРОМ приложении
Возможно, в первом случае накладки с управлением памятью как-то
рассасываются при закрытии треда.
Можно как было указано выше извлечь адрес процедуры, а потом выполнить пуск по адресу
STARTAddr(Long,UNSIGNED=0),SIGNED,PROC,NAME('Cla$START')
... достать адрес процедуры
StartAddr(ProcedureAddress,25000) - запустится процедура с указанным адресом.
Извините, Бальшой Гуру Yufil !
Вы также невнимательны!
Как ни странно, но я почему-то вижу, что написано в кусочке кода,
а именно START - в ОБОИХ случаях. То есть THREAD не тот же, что и вызывающая процедура, а отдельный!
Прежние Ваши советы по CALL и API-аналогам читал и ПРОБОВАЛ.
Результат одинаков.
ПРОШУ ЕЩЁ ОТКЛИКОВ.
Вы также невнимательны!
Как ни странно, но я почему-то вижу, что написано в кусочке кода,
а именно START - в ОБОИХ случаях. То есть THREAD не тот же, что и вызывающая процедура, а отдельный!
Прежние Ваши советы по CALL и API-аналогам читал и ПРОБОВАЛ.
Результат одинаков.
ПРОШУ ЕЩЁ ОТКЛИКОВ.
А какой смысл вызывать по Call, если не секрет? Почему нельзя процедуру откомпилировать просто как автономную DLL?Митрий писал(а):Извините, Бальшой Гуру Yufil !
Вы также невнимательны!
Как ни странно, но я почему-то вижу, что написано в кусочке кода,
а именно START - в ОБОИХ случаях. То есть THREAD не тот же, что и вызывающая процедура, а отдельный!
Прежние Ваши советы по CALL и API-аналогам читал и ПРОБОВАЛ.
Результат одинаков.
ПРОШУ ЕЩЁ ОТКЛИКОВ.
У меня как раз есть кларионовские процедуры, вызываемые по Call+Start, это плагины к основной программе, определяющие дополнительный функционал самим фактом, приложен плагин или нет. Но для них строжайшее требование - компиляция с тем же словарём, что и основная программа. И OLE в них вызываются (правда, не Excel)
И есть некоторые танцы с бубном при подключении модуля, правда, именно для ABC, связанные с инициализацией методов GlobalErrors и IniMgr. Для модулей, вызываемых по Call они, естественно, остаются неинициализированными. Поэтому приходится их инициализировать... эээ, перректально...
Хотя, возможно, в последних версиях Кларион эта проблема и закрыта, проверить лень.
Вы правы, уважаемый Yufil. Потребность - плагины.
Скомпилированы с общим словарём, как и у Вас.
С инициализацией - полный порядок, это решено по образу и подобию последнего предложения Юрия Философова из старой темы "Запуск процедуры из внешней DLL" от 11.02.2004г.
А не правы Вы , как я начал понимать в следующем:
При передаче команд "ВЕЛИКОЛЕПНОМУ" используется последовательно UNLOCKTHREAD(), <команда>, LOCKTHREAD().
А между тем главный процесс получает события, такие, например, как EVENT:TIMER.
И что особенно интересно, если процедура выгрузки в Excel работает из библиотеки, собранной CLARION'ом в приложение (1 ВАРИАНТ), то вот это самое EVENT:TIMER не поступает на ACCEPT потому как ещё не закончена обработка текущего события активного процесса.
А вот во ВТОРОМ случае - когда вызов произведён из плагина - CLARION не почему-то понимает, что это тож его произведение и считает его "чужой процедурой" - то есть генерит событие и передаёт управление на ACCEPT другого окна, хотя обработка в текущем ACCEPTE (плагина) не закончена. И если этот момент попал между UNLOCKTHREAD и LOCKTHREAD - ВОТ ТУТ-ТО И ЕСТЬ "ГРАБЛИ" .
То есть, используя 0{PROP:TIMER} = 0 в каждом активном окне до передачи данных в EXCEL (а затем восстанавливая прежние значения), удалось избавиться от ВЫРУБОНА .
НО ПРОБЛЕМА ОСТАЛАСЬ! ПОМОГИТЕ СОВЕТОМ:
Если пользователь щёлкает мышью в других окнах - события ведь происходят, управление внезапно передаётся другому ACCEPT'у и повторяется прежний дрянной эффект.
Как же запретить это щёлканье...?
Скомпилированы с общим словарём, как и у Вас.
С инициализацией - полный порядок, это решено по образу и подобию последнего предложения Юрия Философова из старой темы "Запуск процедуры из внешней DLL" от 11.02.2004г.
А не правы Вы , как я начал понимать в следующем:
При передаче команд "ВЕЛИКОЛЕПНОМУ" используется последовательно UNLOCKTHREAD(), <команда>, LOCKTHREAD().
А между тем главный процесс получает события, такие, например, как EVENT:TIMER.
И что особенно интересно, если процедура выгрузки в Excel работает из библиотеки, собранной CLARION'ом в приложение (1 ВАРИАНТ), то вот это самое EVENT:TIMER не поступает на ACCEPT потому как ещё не закончена обработка текущего события активного процесса.
А вот во ВТОРОМ случае - когда вызов произведён из плагина - CLARION не почему-то понимает, что это тож его произведение и считает его "чужой процедурой" - то есть генерит событие и передаёт управление на ACCEPT другого окна, хотя обработка в текущем ACCEPTE (плагина) не закончена. И если этот момент попал между UNLOCKTHREAD и LOCKTHREAD - ВОТ ТУТ-ТО И ЕСТЬ "ГРАБЛИ" .
То есть, используя 0{PROP:TIMER} = 0 в каждом активном окне до передачи данных в EXCEL (а затем восстанавливая прежние значения), удалось избавиться от ВЫРУБОНА .
НО ПРОБЛЕМА ОСТАЛАСЬ! ПОМОГИТЕ СОВЕТОМ:
Если пользователь щёлкает мышью в других окнах - события ведь происходят, управление внезапно передаётся другому ACCEPT'у и повторяется прежний дрянной эффект.
Как же запретить это щёлканье...?
Понятно... и с этим потыкался... С этого и надо было начинать. Лучший вариант - перейти на CW6Митрий писал(а):Вы правы, уважаемый Yufil. Потребность - плагины.
Скомпилированы с общим словарём, как и у Вас.
С инициализацией - полный порядок, это решено по образу и подобию последнего предложения Юрия Философова из старой темы "Запуск процедуры из внешней DLL" от 11.02.2004г.
А не правы Вы , как я начал понимать в следующем:
При передаче команд "ВЕЛИКОЛЕПНОМУ" используется последовательно UNLOCKTHREAD(), <команда>, LOCKTHREAD().
А между тем главный процесс получает события, такие, например, как EVENT:TIMER.
И что особенно интересно, если процедура выгрузки в Excel работает из библиотеки, собранной CLARION'ом в приложение (1 ВАРИАНТ), то вот это самое EVENT:TIMER не поступает на ACCEPT потому как ещё не закончена обработка текущего события активного процесса.
А вот во ВТОРОМ случае - когда вызов произведён из плагина - CLARION не почему-то понимает, что это тож его произведение и считает его "чужой процедурой" - то есть генерит событие и передаёт управление на ACCEPT другого окна, хотя обработка в текущем ACCEPTE (плагина) не закончена. И если этот момент попал между UNLOCKTHREAD и LOCKTHREAD - ВОТ ТУТ-ТО И ЕСТЬ "ГРАБЛИ" .
То есть, используя 0{PROP:TIMER} = 0 в каждом активном окне до передачи данных в EXCEL (а затем восстанавливая прежние значения), удалось избавиться от ВЫРУБОНА .
НО ПРОБЛЕМА ОСТАЛАСЬ! ПОМОГИТЕ СОВЕТОМ:
Если пользователь щёлкает мышью в других окнах - события ведь происходят, управление внезапно передаётся другому ACCEPT'у и повторяется прежний дрянной эффект.
Как же запретить это щёлканье...?
А здесь надо деактивировать OLE на Event:LoseFocus и снова активировать на Event:GainFocus. А ещё перед закрытием окна уничтожить OLE командой Destroy.
Уважаемый Бааааааальшой Гуру Yufil!
Недопонял:
А ведь фокус утрачивается внезапно и непредсказуемо. И грабли-то, именно (как я понял) - когда идёт обработка события для BUTTON'а EVENT:ACCEPTED при последовательной посылке EXCEL'у РЯДА КОМАНД, т.е. вида UNLOCKTHREAD <команда1> LOCKTHREAD, UNLOCKTHREAD <команда2> LOCKTHREAD, ... UNLOCKTHREAD <команда_N> LOCKTHREAD.
И именно в момент когда исполнено UNLOCKTHREAD и не исполнено LOCKTHREAD. Как же это поймать.
НЕ ДОГОНЯЮ ...
Недопонял:
1) В CW6 такой проблемы нет?Лучший вариант - перейти на CW6
2) Уничтожение, естствно, делаю. А что, если деактивировать OLE по утрате фокуса, а затем активировать по получении - разве я смогу отгрузить всё? Или надо начать сначала? Или с какого места - как узнать?А здесь надо деактивировать OLE на Event:LoseFocus и снова активировать на Event:GainFocus. А ещё перед закрытием окна уничтожить OLE командой Destroy.
А ведь фокус утрачивается внезапно и непредсказуемо. И грабли-то, именно (как я понял) - когда идёт обработка события для BUTTON'а EVENT:ACCEPTED при последовательной посылке EXCEL'у РЯДА КОМАНД, т.е. вида UNLOCKTHREAD <команда1> LOCKTHREAD, UNLOCKTHREAD <команда2> LOCKTHREAD, ... UNLOCKTHREAD <команда_N> LOCKTHREAD.
И именно в момент когда исполнено UNLOCKTHREAD и не исполнено LOCKTHREAD. Как же это поймать.
НЕ ДОГОНЯЮ ...
Уважаемый Бааааааальшой Гуру Yufil!
Это не я себя так назвал, а администратор сайта. И нечего иронизировать...
Недопонял:
1) В CW6 такой проблемы нет?
В CW6 настоящие треды, там этой проблемы действительно нет. Есть другие.
А в 55 есть только псевдотреды, которые с OLE действительно плохо сочетаются.
2) Уничтожение, естствно, делаю. А что, если деактивировать OLE по утрате фокуса, а затем активировать по получении - разве я смогу отгрузить всё? Или надо начать сначала? Или с какого места - как узнать?
Так в CW55 реально работает ровно ОДНА задача. Если идёт заполнение таблицы, переключение на другой экран невозможно.
А если произошло переключение, то таблица НЕ ЗАПОЛНЯЕТСЯ!
КОМАНД, т.е. вида UNLOCKTHREAD <команда1> LOCKTHREAD, UNLOCKTHREAD <команда2> LOCKTHREAD, ... UNLOCKTHREAD <команда_N> LOCKTHREAD.
UnlockThread/LockThread - это вообще не о том...
Это говорит, что кларионовский Accept не должен ловить сообщения.
Мой номер ICQ 75-924-439, давай в Аське потрындим....
Это не я себя так назвал, а администратор сайта. И нечего иронизировать...
Недопонял:
1) В CW6 такой проблемы нет?
В CW6 настоящие треды, там этой проблемы действительно нет. Есть другие.
А в 55 есть только псевдотреды, которые с OLE действительно плохо сочетаются.
2) Уничтожение, естствно, делаю. А что, если деактивировать OLE по утрате фокуса, а затем активировать по получении - разве я смогу отгрузить всё? Или надо начать сначала? Или с какого места - как узнать?
Так в CW55 реально работает ровно ОДНА задача. Если идёт заполнение таблицы, переключение на другой экран невозможно.
А если произошло переключение, то таблица НЕ ЗАПОЛНЯЕТСЯ!
КОМАНД, т.е. вида UNLOCKTHREAD <команда1> LOCKTHREAD, UNLOCKTHREAD <команда2> LOCKTHREAD, ... UNLOCKTHREAD <команда_N> LOCKTHREAD.
UnlockThread/LockThread - это вообще не о том...
Это говорит, что кларионовский Accept не должен ловить сообщения.
Мой номер ICQ 75-924-439, давай в Аське потрындим....
- Admin
- Администратор
- Сообщения: 3959
- Зарегистрирован: 05 Июль 2005, 15:59
- Откуда: Хабаровск
- Благодарил (а): 25 раз
- Поблагодарили: 22 раза
- Контактная информация:
Не стебитесь над званием!Yufil писал(а):Уважаемый Бааааааальшой Гуру Yufil!
Это не я себя так назвал, а администратор сайта. И нечего иронизировать...
Человек всегда может ошибаться а звание дают за заслуги перед обществом
А то я могу и того кто любит шутить .... Гуру каким нибудь сделать
Рай совершает ошибки ничуть не реже чем ад. Просто у него хорошая пресса