Внутри Callback-функции не могу вызывать другие функции

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Jupiter
Обычный пользователь
Обычный пользователь
 
Сообщения: 51
Зарегистрирован: 17.01.2006 (Вт) 12:34

Внутри Callback-функции не могу вызывать другие функции

Сообщение Jupiter » 17.01.2006 (Вт) 13:11

Здравствуйте.
Проблема с функцией обратного вызова (Callback).
Я пользуюсь некой DLL через Declare. Эта DLL требует инициализации и передаче ей указателя на мою Callback-функцию (на VB), которую эта DLL будет дергать в неопределенные моменты. Пока все ясно. Проблема в том, что я не могу размещать внутри моей Callback-функции никакие вызовы других функций с передачей аргументов. ИНаче при вызове из-под DLL происходит крах всего на свете. Если же внутри моей функции только обращение к переменным и вызовы без передачи аргументов, то все нормально. У меня такое впечатление, что дело в подмене стека вызовов. Типа, во время вызова из-под DLL в регистре SP (или как он там называется) содержится указатель на стек другого процесса. Хотя, я в этом не силен. Вроде, DLL должна пользоваться стеком родительского процесса. В общем, не пойму, как лечить.

Дополнительно сообщю, что DLL написана не мной на С++, публичные вызовы по StdDecl.

Вот в сильно упрощенном виде код:
Код: Выделить всё
' Здесь я объявляю функцию инициализации DLL

Public Declare Function init_DLL Lib "XXX.dll" (ByVal CallbackFunc As Long) As Long

' Это типа точка входа

Public Sub Main()
   ' Инициирую DLL с передачей ей указателя на мою Callback-функцию
     init_DLL(AddressOf CallbackFunc)
End Sub

' А вот и сама Callback-функция в соответствием с требованием DLL

Public Function CallbackFunc(ByVal param1 As Long, ByVal param2 As Long) As Long
    ' невозможно делать никаких вызовов,  требующих передачи аргументов
End Function

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 17.01.2006 (Вт) 13:23

Чё-то ерунда какая-то...
Покажи, наверное, прототипы функций как они указаны в сишной документации.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Jupiter
Обычный пользователь
Обычный пользователь
 
Сообщения: 51
Зарегистрирован: 17.01.2006 (Вт) 12:34

Сообщение Jupiter » 17.01.2006 (Вт) 13:32

Вот описания на C из документации. Инициализация (init_DLL) происходит нормально.
Код: Выделить всё
DWORD init_DLL (VLSDK_CALLBACK* callback);

// Прототип функции обратного вызова
typedef int (__stdcall VLSDK_CALLBACK)(DWORD param1, DWORD param2);

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 17.01.2006 (Вт) 13:36

"Указатель на функцию, возвращающую int" - это
Код: Выделить всё
typedef int (__stdcall *VLSDK_CALLBACK)(DWORD param1, DWORD param2);


А что такое
Код: Выделить всё
typedef int (__stdcall VLSDK_CALLBACK)(DWORD param1, DWORD param2);
, я как-то не знаю...


Хотя нет, по идее пофигу... Чё-то тут не так.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 17.01.2006 (Вт) 13:47

А вызовы чего производятся внутри?
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 17.01.2006 (Вт) 13:55

Может у него эта функция асинхронно вызывается?
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 17.01.2006 (Вт) 13:59

2Jupiter: Попробуй выводить значение GetCurrentThreadID в sub Main и в этой функции. Если они отличаются, то :?
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

Jupiter
Обычный пользователь
Обычный пользователь
 
Сообщения: 51
Зарегистрирован: 17.01.2006 (Вт) 12:34

Сообщение Jupiter » 17.01.2006 (Вт) 14:55

Вот стал готовить ответы на выши вопросы, при этом запустил программу из ехе-шника. Вы, наверное, будете бить меня ногами за то, что чайник, но из ехе-шника все заработало без проблем! То есть, что выходит, что я, находясь в IDE, запускал DLL, которая дергала асинхронно мой код. Возможно, когда запускаешь из IDE, то там вообще на самом деле другой код, с отладкой ? Может, это само сабой разумеется для профессионалов, что если у тебя есть AddressOf, то это все может работать толко в скомпилированном виде?

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 17.01.2006 (Вт) 15:07

Нет конечно. Работает везде. Но не всегда. А ты отлаживал программу при этом?
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Jupiter
Обычный пользователь
Обычный пользователь
 
Сообщения: 51
Зарегистрирован: 17.01.2006 (Вт) 12:34

Сообщение Jupiter » 17.01.2006 (Вт) 15:57

>А ты отлаживал программу при этом
Нет, боже упаси! Я на это даже и не расчитывал. Просто нажал кнопку запуска (треугольничек). Внутри у меня была функция Sleep с аргументом (количество микросекунд). Валилось. Решил запускать оттуда таймер, поставил ф. CreateTimer (или как она там называется) - у нее тоже есть аргументы, и тоже валилось. Функции, не требующие аргументов, живут в ней нормально. Мои VB функции, которые здесь же расположены, могут вызываться даже с аргументами.
Надо сказать, что валится из IDE не всегда при первом исполнении. На какой раз свалится - не гарантировано. Но из ЕХЕ я много раз запускал - ни одного сбоя.

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 17.01.2006 (Вт) 16:03

Ну ни фига себе... Не надо так сильно IDE озадачивать больше. Таймер же шлёт сообщения, их же надо обрабатывать...
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 17.01.2006 (Вт) 16:03

Хмм.
Все симптому указывают на то, что параметры передаются неправильно.
Таймер то вызывается синхронно. Так что если у тебя и там валится, значит ты просто неправильно передаеш параметры.
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 17.01.2006 (Вт) 16:06

2GSerg:VB мне кажеться спокойно работает с таймерами...
Просто DispatchMessage направляет это сообщение в указанныую в SetTimer процедуру(если там не было указано окно). Так что я не думаю, что IDE сильно пострадает от таймера.
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 17.01.2006 (Вт) 16:09

VB спокойно работает даже с cdecl, а вот IDE на этом факте падает...
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 17.01.2006 (Вт) 16:23

Гм. У меня некогда не падала...
Если ESP после функции корявый, появлялась ошибка bad dll conversion calling и все. А у тебя разве нет?
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

Tarantul
Бывалый
Бывалый
 
Сообщения: 235
Зарегистрирован: 13.12.2004 (Пн) 16:39
Откуда: IUnknown

Сообщение Tarantul » 17.01.2006 (Вт) 16:25

Насколько я знаю, VB не способен никак работать асинхронно. Стабильности здесь вообще не будет, просто дело случая. Один раз вылетет, другой нет. В IDE вылетает чаще :?

VB спокойно работает даже с cdecl, а вот IDE на этом факте падает...

Это точно :) У меня самого в DLL по умолчанию все функции были cdecl, и exe на VB спокойно их переваривал. А IDE выдавал ошибку "Invalid DLL caling convention". Я еще долго не мог понять в чем дело. Когда наконец понял, поставил в DLL перед функцией "WINAPI" (т.е. __stdcall) и все пошло как надо :)

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 17.01.2006 (Вт) 16:25

Разве нет.
А ты вообще как вызваешь cdecl-функции?
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 17.01.2006 (Вт) 16:36

В смысле как? Так же как и stdcall.
Кстати, что там с моим агентом? А то я прям весь расстроен...
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 17.01.2006 (Вт) 16:41

Да???
Ты крут, потому что VB так не умеет и я тоже...

А насчёт агента - есть SDK на сколько то там сотен метров...
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 17.01.2006 (Вт) 16:44

А примера с ассистентом нет?
Не знаю, по крайней мере с одним параметром работало прекрасно.
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

Jupiter
Обычный пользователь
Обычный пользователь
 
Сообщения: 51
Зарегистрирован: 17.01.2006 (Вт) 12:34

Сообщение Jupiter » 17.01.2006 (Вт) 17:48

ANDLL писал(а):2Jupiter: Попробуй выводить значение GetCurrentThreadID в sub Main и в этой функции. Если они отличаются, то :?

Попробовал. Они ОТЛИЧАЮТСЯ. Это я из под IDE с горем пополам установил.
Кроме того, я рано радовался. Оказывается, в ЕХЕ тоже нифига не работает. Просто не падает. Там на вызовах, наверное, исключение вываливается и все. То есть Callback функция
Код: Выделить всё
Public Function CallbackFunc(ByVal param1 As Long, ByVal param2 As Long) As Long
  '  Beep 1000, 100

    AddLogMsg "Вошли в Callback"
    AddLogMsg GetCurrentThreadId()
   
    ' EnterCriticalSection criticalSection
  '..............     
   ' LeaveCriticalSection criticalSection
   
    AddLogMsg "Вышли из Callback"
End Function


"Вошли в Callback" пишет, а "Вышли из Callback" уже нет :cry: :cry: :cry:

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 17.01.2006 (Вт) 18:02

Если отличаются значит вызов асинхронный.
Что такое сабклассинг представляеш?
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

Jupiter
Обычный пользователь
Обычный пользователь
 
Сообщения: 51
Зарегистрирован: 17.01.2006 (Вт) 12:34

Сообщение Jupiter » 17.01.2006 (Вт) 18:49

ANDLL писал(а):Если отличаются значит вызов асинхронный.
Что такое сабклассинг представляеш?

Это когда ты подменяешь стандартный обработчик событий своим собственным? Как мне это использовать?
Асинхронный вызов я хотел обрабатывать критической секцией, но там до нее дело не доходит...

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 17.01.2006 (Вт) 18:56

А VB про твои критические секции знает?
Да сабклассинг это оно самое.
Сабклассиш свое окно на предмет сообщения скажем, UWM_COMMAND1=WM_USER+50.
Потом в своей функции пишеш
CallbackFunc=SendMessage(hWnd_твоего_окна, UWM_COMMAND1,param1, param2)
hWnd_твоего_окна - это переменная модуля, а не свойство формы.
Сам не пробовал, но вроде бы должно работать... Уже в обработчике UWM_COMMAND1 делаеш то, что тебе нужно.
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 17.01.2006 (Вт) 18:59

Jupiter
Критические секции, о которых не знает та dll, тебе не помогут.

ANDLL
Силюсь понять, причём тут сабклассинг. но не получается...
И ставь ь после шипящих во втором лице, если не трудно, раздражает безумно...
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 17.01.2006 (Вт) 19:01

2GSerg: постараюсЬ. SendMessage певратит асинхронный вызов в синхронный.
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 17.01.2006 (Вт) 19:05

Если и это не поможет - значит заноси Critical sections в dll.
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

Jupiter
Обычный пользователь
Обычный пользователь
 
Сообщения: 51
Зарегистрирован: 17.01.2006 (Вт) 12:34

Сообщение Jupiter » 17.01.2006 (Вт) 19:07

Я понял. Я должен делигировть вызов моей callcack-функции обработчику сообщений окна. Я нечто подобное делал. Это остроумнее, чем применять позорные таймеры. Я попробую, НО у меня опасение: если даже простенькие GetCurrentThreadId без параметров способна свалить callcack-функцию, то SendMessage с параметрами - еще хуже. Кстати, правильно ли я понял, что SendMessage (в отличие от PostMessage) будет ждать окончания обработки и только потом вернет управление из callcack-функции?

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 17.01.2006 (Вт) 19:08

SendMessage откуда?
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Jupiter
Обычный пользователь
Обычный пользователь
 
Сообщения: 51
Зарегистрирован: 17.01.2006 (Вт) 12:34

Сообщение Jupiter » 17.01.2006 (Вт) 19:09

ANDLL писал(а):Если и это не поможет - значит заноси Critical sections в dll.

DLL - чужая. Если ничего не получится, то я буду писать свою переходную DLL на С (очень не хочется).

След.

Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: Google-бот и гости: 159

    TopList