Здравствуйте, ZAMUNDA, Вы писали:
ZAM>Здравствуйте, Аноним, Вы писали:
А>>Were i Zamunda, AddressOf здесь не нужен, вроде я пробовал — тогда ошибку дает... ZAM>Не может такого быть. Не пробовали вы ничего, если такое говорите.
А я утверждаю, уважаемый, вот только что попробовал, специально для вас, — с AddressOf Бейсик вылетел!И у вас вылетит!
А>>Сергей Мухин — спасибо за муки творчества,признателен за внимание! Я не привожу Declare, ибо как и все копирую WIN API, как и должно! ZAM>В MSDN приведены декларации на C, и неправильный перевод их на VB это самая частая ошибка. Даже базы с готовыми декларациями, которыми вам стоило бы воспользоваться (ApiViewer 200x например), не всегда верны.
Я знаю, что декларации бывают с ошибками, но эта, взятая именно из "API Text Viewer"-a, верная:
Public Declare Function CreateThread Lib"kernel32" (lpThreadAttributes As SECURITY_ATTRIBUTES, ByVal dwStackSize As Long, lpStartAddress As Long, lpParameter As Any, ByVal dwCreationFlags As Long, lpThreadId As Long) As Long
Хорошо, если вы такой всезнающий, приведите мне работающий пример с запуском,один сразу после другого, двух тредов CreateThread, причем в обоих нужно запускать функции с бесконечным циклом внутри! Можем?
Re[8]: CreateThread
От:
Аноним
Дата:
03.02.10 10:00
Оценка:
Здравствуйте, ononim, Вы писали:
O>не ну етоже п..ц какой то. Я не эти скобки имел ввиду. O>В С++ — MyFunction() — это вызов MyFunction. MyFunction — это указатель на MyFunction, тоже самое что &MyFunction. O>В VB, по моим смутным воспоминаниям QBasic'а — MyFunction — это вызов MyFunction. Значит должен быть некий оператор указателя чтобы взять указатель, ибо написание имени функции в нем это ее вызов.
Не выражаемся!
AddressOf если вы имели в виду, то с ним не работает CreateThread Бейсик вылетает, а без этого "указателя" (AddressOf) — все нормально работает, я об этом выше упоминал и думал, что вы прочли. Нет, все равно, при бесконечном цикле в MyFunction, не получается еще что-то после этой CreateThread выполнить... Наверное так и должно быть? А если мне надо два таких треда создать, то как быть?
Здравствуйте, Аноним, Вы писали: А> Я знаю, что декларации бывают с ошибками, но эта, взятая именно из "API Text Viewer"-a, верная:
А>
А>Public Declare Function CreateThread Lib"kernel32" (lpThreadAttributes As SECURITY_ATTRIBUTES, ByVal dwStackSize As Long, lpStartAddress As Long, lpParameter As Any, ByVal dwCreationFlags As Long, lpThreadId As Long) As Long
А>
Гм, я не специалист по VB. но где stdcall? или в VB все stdcall?
А>Хорошо, если вы такой всезнающий, приведите мне работающий пример с запуском,один сразу после другого, двух тредов CreateThread, причем в обоих нужно запускать функции с бесконечным циклом внутри! Можем?
это не ко мне вопрос, но в чем проблема то? Работать будет 100% даже странно, Аноним предпологает, что такая базовая ф-ия как CreateThread плохо работает!!. Что бы убедиться в этом еще более уверенно, можно запустить thread'ы с низким приоритетом!
Здравствуйте, Аноним, Вы писали:
А> AddressOf если вы имели в виду, то с ним не работает CreateThread Бейсик вылетает, а без этого "указателя" (AddressOf) — все нормально работает, я об этом выше упоминал и думал, что вы прочли. Нет, все равно, при бесконечном цикле в MyFunction, не получается еще что-то после этой CreateThread выполнить... Наверное так и должно быть? А если мне надо два таких треда создать, то как быть?
Уважаемый Аноним, из прочитанной мной ветки я могу сделать только один вывод — никакой поток у Вас не создаётся, а Ваша MyFunction запускается в контексте текущего потока, и поскольку она содержит бесконечный цикл после неё ничего не выполнятся.
---
The optimist proclaims that we live in the best of all possible worlds; and the pessimist fears this is true
O>>не ну етоже п..ц какой то. Я не эти скобки имел ввиду. O>>В С++ — MyFunction() — это вызов MyFunction. MyFunction — это указатель на MyFunction, тоже самое что &MyFunction. O>>В VB, по моим смутным воспоминаниям QBasic'а — MyFunction — это вызов MyFunction. Значит должен быть некий оператор указателя чтобы взять указатель, ибо написание имени функции в нем это ее вызов.
А> AddressOf если вы имели в виду, то с ним не работает CreateThread Бейсик вылетает,
значит функция корявая. __stdcall (или как там он в бейсике) указать не забыли?
код пля в студию
Как много веселых ребят, и все делают велосипед...
А>но — любой код после этой строчки — не выполняется, как будто его нет и в помине! В чем ошибка у меня не могу понять? А если я, например, хочу написать еще одно создание треда непосредственно после первого, А>
Многопоточность в VB6 это такой способ найти грабли на пустом месте...
Вот рабочий пример:
Public Declare Function CreateThread Lib"kernel32" _
(ByVal lpThreadAttributes As Long, _
ByVal dwStackSize As Long, _
ByVal lpStartAddress As Long, _
ByVal lpParameter As Long, _
ByVal dwCreationFlags As Long, _
lpThreadId As Long) As Long
Function Task1(ByVal Arg As Long) As Long' Помним, что внутри потока нельзя ни обрабатывать исключения, ни обращаться к методам COM обьектов ... ничерта нельзя
' Никакого вывода на экран сделать нельзя. Но C++-й отладчик показывает, что этот поток живет нормально.Dim i As Long
For i = 0 To 10000000
'Next i
End Function
Sub Main()
Dim lpThreadId As Long, ret As Long
ret = CreateThread(0, 0, AddressOf Task1, 0, 0, lpThreadId)
MsgBox"ret=" + CStr(ret) + " lpThreadId=" + CStr(lpThreadId)
End Sub
Здравствуйте, wallaby, Вы писали:
А>> AddressOf если вы имели в виду, то с ним не работает CreateThread Бейсик вылетает, а без этого "указателя" (AddressOf) — все нормально работает, я об этом выше упоминал и думал, что вы прочли. Нет, все равно, при бесконечном цикле в MyFunction, не получается еще что-то после этой CreateThread выполнить... Наверное так и должно быть? А если мне надо два таких треда создать, то как быть?
W>Уважаемый Аноним, из прочитанной мной ветки я могу сделать только один вывод — никакой поток у Вас не создаётся, а Ваша MyFunction запускается в контексте текущего потока, и поскольку она содержит бесконечный цикл после неё ничего не выполнятся.
MyFunction должна получать параметр, раз она является запускаемой CreateThread функцией. Когда Аноним приведет в соответствие, то VB будет ругаться на такое использование функции. Если она не имеет параметра, то она не может быть запущена через CreateThread.
Здравствуйте, Vi2, Вы писали:
Vi2>MyFunction должна получать параметр, раз она является запускаемой CreateThread функцией. Когда Аноним приведет в соответствие, то VB будет ругаться на такое использование функции. Если она не имеет параметра, то она не может быть запущена через CreateThread.
Это не совсем так. И даже совсем не так. Ф-ия без параметров, если пройдет компилятор, совершенно безобидно будет вызвана. Это конечно для Windows 32. Для других — не знаю.
Дело в том, что __stdcall очень терпимо относится, если при вызове передается больше параметров (точнее на стеке больше параметров), чем ф-ия может принять.
Здравствуйте, Сергей Мухин, Вы писали:
СМ>Это не совсем так. И даже совсем не так. Ф-ия без параметров, если пройдет компилятор, совершенно безобидно будет вызвана. Это конечно для Windows 32. Для других — не знаю. СМ>Дело в том, что __stdcall очень терпимо относится, если при вызове передается больше параметров (точнее на стеке больше параметров), чем ф-ия может принять.
Забыл сказать главное: конечно это грязный хак и делать запрещено.
---
С уважением,
Сергей Мухин
Re[11]: CreateThread
От:
Аноним
Дата:
04.02.10 15:01
Оценка:
Здравствуйте, Vi2, Вы писали:
Vi2>MyFunction должна получать параметр, раз она является запускаемой CreateThread функцией. Когда Аноним приведет в соответствие, то VB будет ругаться на такое использование функции. Если она не имеет параметра, то она не может быть запущена через CreateThread.
И все-таки, как ни странно и обидно, сам поражаюсь, но MyFunction прекрасненько запускается и все что предписано выполняет! это такие действия, что не скрыть (и все выполняет параллельно с другими функциями формы проекта), и запустил ее CreateThread!Хотя это видимо нечаянно получилось и вполне можно было просто запустить непосредственно MyFunction, а не CreateThread? Вы ведь не думаете,что я вас мистифицирую? Иначе бы я наоборот ныл бы и плакакл, что ничего не запускается, а я всего-лишь жалуюсь, что еще один подобный CreateThread запустить не могу, а вдруг понадобится...мало ли...
То есть я хотел запустить параллельно с основным процессом с помощью CreateThread, но видимо просто запустилась MyFunction, я прав?
Так как Мухин думает, что ошибка в MyFunction, привожу и ее:
Public mycycle As Boolean
Public MyHandle As Long'Public Function MyFunction()
mycycle = True
Do While (mycycle)
If (MyHandle <> 0) Then
AnyOtherFunction ' некая функция, неважноDebug.Print"MyFunction"
Sleep (100)
DoEvents
End If
Sleep (200)
DoEvents
Loop
End Function
Re[2]: CreateThread
От:
Аноним
Дата:
04.02.10 15:08
Оценка:
Здравствуйте, Chorkov, Вы писали:
C>Многопоточность в VB6 это такой способ найти грабли на пустом месте...
C>Вот рабочий пример: C>
C>Public Declare Function CreateThread Lib"kernel32" _
C> (ByVal lpThreadAttributes As Long, _
C> ByVal dwStackSize As Long, _
C> ByVal lpStartAddress As Long, _
C> ByVal lpParameter As Long, _
C> ByVal dwCreationFlags As Long, _
C> lpThreadId As Long) As Long
C>Function Task1(ByVal Arg As Long) As Long
C>' Помним, что внутри потока нельзя ни обрабатывать исключения, ни обращаться к методам COM обьектов ... ничерта нельзя
C>' Никакого вывода на экран сделать нельзя. Но C++-й отладчик показывает, что этот поток живет нормально.
C> Dim i As Long
C> For i = 0 To 10000000
C> '
C> Next i
C>End Function
C>Sub Main()
C> Dim lpThreadId As Long, ret As Long
C> ret = CreateThread(0, 0, AddressOf Task1, 0, 0, lpThreadId)
C> MsgBox"ret=" + CStr(ret) + " lpThreadId=" + CStr(lpThreadId)
C>End Sub
C>
и что? MsgBox выдается на экран? А у меня вроде никак... и от AddressOf-а вылетает отладчик Бейсик-а!
Здравствуйте, Аноним, Вы писали:
А> И все-таки, как ни странно и обидно, сам поражаюсь, но MyFunction прекрасненько запускается и все что предписано выполняет! это такие действия, что не скрыть (и все выполняет параллельно с другими функциями формы проекта), и запустил ее CreateThread!Хотя это видимо нечаянно получилось и вполне можно было просто запустить непосредственно MyFunction, а не CreateThread? Вы ведь не думаете,что я вас мистифицирую? Иначе бы я наоборот ныл бы и плакакл, что ничего не запускается, а я всего-лишь жалуюсь, что еще один подобный CreateThread запустить не могу, а вдруг понадобится...мало ли...
А>Public Function MyFunction()
А>...
А>End Function
Такую функцию можны вызвать такими способами:
i = MyFunction()
i = MyFunction
Call MyFunction()
Call MyFunction
MyFunction
Поэтому когда ты пишешь CreateThread(...., MyFunction, ...), VB, чтобы вычислить аргумент, передаваемый в CreateThread на месте MyFunction, вычисляет выражение "MyFunction", т.е. осуществляет вызов этой функции, и происходит это ДО обращения к CreateThread.
Если бы, как того требует CreateThread, у этой функции был параметр, то VB бы ругнулся, потому как ему нужен был бы аргумент, и вызов был бы таким CreateThread(...., MyFunction(параметр), ...), что уже не вводило бы в заблуждение.
Здравствуйте, Vi2, Вы писали: Vi2>Поэтому когда ты пишешь CreateThread(...., MyFunction, ...), VB, чтобы вычислить аргумент, передаваемый в CreateThread на месте MyFunction, вычисляет выражение "MyFunction", т.е. осуществляет вызов этой функции, и происходит это ДО обращения к CreateThread.
именно. тебе уже об этом говорят раз пять! Проблема давно решена. ты просто настолько наивен в программировании, что не видишь разницу между функцией и ее результатом!
Здравствуйте, Аноним, Вы писали:
А>и что? MsgBox выдается на экран? А у меня вроде никак... и от AddressOf-а вылетает отладчик Бейсик-а!
Да, мой пример работает, а его проверил.
Отчего у тебя вылетает отладчик я не знаю, но инструкция AddressOf в принципе не содержит инструкций, который могут приводить к run-time ошибкам.
Отладчик VB6 падает не от AddressOf, а от многопоточности. (Не предназначен от для отладки многопоточных приложений.)
Самый простой способ их отладки — собрать exe (в настройках проекта поставить галочка "Generate debug information") и запускать его под отладчиком c++.
Кроме того, если ты использовал туже функцию, которую привел в ответе Vi2, то падение в ней вызвано функциями DoEvents, MsgBox, Debug.Print.
Эти функции нельзя вызывать из потока, в котором не инициализирован TLS бэйсика и не инициализирован COM-Apartment.
Кроме того, в этом потоке нет цикла обработки сообщений, потому вызов DoEvents — трижды ошибка.
Re[4]: CreateThread
От:
Аноним
Дата:
05.02.10 17:35
Оценка:
Здравствуйте, Chorkov, Вы писали:
C>Да, мой пример работает, а его проверил. C>Отчего у тебя вылетает отладчик я не знаю, но инструкция AddressOf в принципе не содержит инструкций, который могут приводить к run-time ошибкам. C>Отладчик VB6 падает не от AddressOf, а от многопоточности. (Не предназначен от для отладки многопоточных приложений.) C>Самый простой способ их отладки — собрать exe (в настройках проекта поставить галочка "Generate debug information") и запускать его под отладчиком c++.
Спасибо, попробую...
C>Кроме того, если ты использовал туже функцию, которую привел в ответе Vi2, то падение в ней вызвано функциями DoEvents, MsgBox, Debug.Print. C>Эти функции нельзя вызывать из потока, в котором не инициализирован TLS бэйсика и не инициализирован COM-Apartment. C>Кроме того, в этом потоке нет цикла обработки сообщений, потому вызов DoEvents — трижды ошибка.
Не буду врать — не инициализировал никогда TLS Бэйсика и COM-Apartment (а зачем мне это и как их синициализировать в VB6?), но без AddressOf-а от функций DoEvents, MsgBox, Debug.Print ничего не падает, это только от присутствия AddressOf-а заваливается отладчик, а вот без DoEvents мне никак нельзя — иначе не работают другие куски программы и другим приложениям будет не сладко(но это уже другая история, страна...) Какой же вы цикл обработки сообщений имеете в виду? и для чего он мне? Меня еще интересует как же добиться, чтоб моя прога не зависала в TaskMаnаger-е, когда оператору нужно делать logoff kompa, a on не происходит — скорей всего logoff зависает от моего бесконечного цикла, ...
Здравствуйте, Аноним, Вы писали:
А> А я утверждаю, уважаемый, вот только что попробовал, специально для вас, — с AddressOf Бейсик вылетел!И у вас вылетит!
Неа не вылетит. :-)
А> Я знаю, что декларации бывают с ошибками, но эта, взятая именно из "API Text Viewer"-a, верная:
Разродился наконец. Вот умничка!!! ;-)
Public Declare Function CreateThread Lib"kernel32" (lpThreadAttributes As SECURITY_ATTRIBUTES, ByVal dwStackSize As Long, ByVal lpStartAddress As Long, lpParameter As Any, ByVal dwCreationFlags As Long, lpThreadId As Long) As Long
... и про AddressOf не забудь. И если тебе не хочется париться с SECURITY_ATTRIBUTES, объяви первый параметр ByVal lpThreadAttributes As Long и передай 0.
А>Хорошо, если вы такой всезнающий, приведите мне работающий пример с запуском,один сразу после другого, двух тредов CreateThread, причем в обоих нужно запускать функции с бесконечным циклом внутри! Можем? :???:
Ещё как можем! А надо ещё?
PS: простите некогда было. Вот только зашёл. Если кто уже ответил, прошу прощения.
PPS: По прочим вопросам сюда