|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
Я для передачи команд (строк) между приложениями использую два IPC-метода: 1) Mailslot 2) SendMessage(WM_COPYDATA) -сейчас почти нигде не оставил в пользу первого В переписываемом .Net приложении я делаю упор на Юникод, т.е. все API декларируются Код: vbnet 1.
все структуры с намеком на строки Код: vbnet 1.
Чтение /запись в MailSlot базируется на ф-циях ReadFile/WriteFile. В случае WM_COPYDATA передается структура COPYDATASTRUCT. И в том и другом случае речь идет о передаче НАБОРА БАЙТОВ а не строк, поэтому в оригинале нет отдельных определений "A" и "W" Вот собственно не знаю как поступить. Могу оставаться в ANSI (для этих методов): Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21.
Могу "мигрировать на Юникод" Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21.
Сложность выбора еще в том, что у меня есть C++(ANSI) -модуль, в котором также присутствует MailSlot , он обменивается c VB.Net -приложением (только EN-строки), но это же VB.Net обменивается с другим VB.Net. Если посылать раздельно ANSI/Unicode (в разные приложения) можно без проблем, то приемник один (т.е. в него нельзя слать ANSI/Unicode кашу). VB.Net компоненты могут передавать меж собой "русские" (не-EN) тексты. От требования к системе: русский язык для не-юникод программ для "русской версии" я хочу отказаться. Если я оставлю ANSI в этом вопросе, не получу ли я проблем с передачей русского текста (при отключенной поддержке для не-Юникод программ)? Комп то вроде по любому один и тот же. Как закодирует, так и раскодирует. Как тут посоветуете поступить? И еще. Конечно не стоит мешать API с .Net, хотя бы в случае с mailslot, нельзя как-то заменить ReadFile/WriteFile на StreamWriter/Reader? Т.е. явно задавать/определять кодировку при чтении записи в файл (т.е в Mailslot) UTF8 с флагом или как там его(недавно обсуждали)/Default ANSI, handle mailslot-а известен.??? ... |
|||
:
Нравится:
Не нравится:
|
|||
10.02.2015, 12:29 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
base64 кодируй при отправке, при приёме декодируй ... |
|||
:
Нравится:
Не нравится:
|
|||
10.02.2015, 12:34 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
маршаллинг прарметров явно задай (как массив байтов с указаием параметра-длины) , буферу будет насрать на вызов A или U Дмитрий77От требования к системе: русский язык для не-юникод программ для "русской версии" я хочу отказаться. это правильно Дмитрий77нельзя как-то заменить ReadFile/WriteFile на StreamWriter/Reader? Т.е. явно задавать/определять кодировку при чтении записи в файл (т.е в Mailslot) UTF8 с флагом или как там его(недавно обсуждали)/Default ANSI, handle mailslot-а известен.??? никакого смысла. получил пакет в виде набора байтов - интерпретируй как хочешь, поток не поможет можно рассмотреть вариант - во всех приложениях использовать UTF-8 ... |
|||
:
Нравится:
Не нравится:
|
|||
10.02.2015, 13:17 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
Дмитрий77, при работе с набором байтов разницы между ANSI и Unicode не будет. Однако по моему ты неправильно объявил ReadFile/WriteFile/COPYDATASTRUCT. Ты говоришь об обмена байтами, а используешь тип String для lpBuffer/lpData. По моему там должен быть IntPtr т.к. в С/С++ они объявлены как LPVOID. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.02.2015, 13:54 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
Давайте про mailslot только рассуждать чтоб не путаться. Ну, насколько я понимаю, что если 1) строка "русская" 2) язык системы для не-юникода - "китайский" 3) WriteFile и ReadFile декларированы как ANSI т.е. (...ByVal lpBuffer As String) то на выходе все таки получим фигню а не "русский". Т.е. не сумеет он в общем случае кодировать в ANSI и декодировать из ANSI. Так? Т.е. все-таки передавать надо Unicode? >маршаллинг прарметров явно задай Какая разница в данном случае написать слово Unicode перед ф-цией или лепить <Marshall.> перед as String?. Задекларировав функции как Declare Unicode Function , ну или прописав маршалинг параметров как Юникод я эту задачу решаю (передается Юникод хз там в какой кодировке согласно API понятиям но без искажений). Естественно хочется As String для простоты использования. === Но остается тогда нерешенной следующая задача: Предположим есть exe, есть mailslot. Одно приложение шлет в него ANSI (C++, только EN, переписывать/перекомпилировать на Unicode не буду). Другое приложение шлет в него Unicode. Как извернуться (с единственным mailslot)? Объясню почему я вспомнил про StreamWriter/Reader. Потому что mailslot -по сути файл с операциями записи чтения в него. В StreamWriter/Reader есть параметр Encoder, применяя который можно задать BOM (явное указание UTF8 например). Т.е. нельзя ли эту автоматику как то присобачить? Приходит строка с BOM -конвертируется из UTF8, без BOM -значит ANSI. Хотя опять же, не уверен. BOM же в начало файла ставится а как это на MailSlot переложить... Функции для MailSlot у меня со времен VB6 такие, декларации для ANSI и Unicode я привел выше. Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49.
Видимо надо тест-проект создавать и играться. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.02.2015, 14:07 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
bazileДмитрий77, при работе с набором байтов разницы между ANSI и Unicode не будет. Однако по моему ты неправильно объявил ReadFile/WriteFile/COPYDATASTRUCT. Ты говоришь об обмена байтами, а используешь тип String для lpBuffer/lpData. По моему там должен быть IntPtr т.к. в С/С++ они объявлены как LPVOID. Ты абсолютно прав. В оригинале там конечно байты, а не строки. По этой причине в ReadFile/WriteFile/COPYDATASTRUCT и нет деления на "A" и "W". Но я то знаю что я работаю ТОЛЬКО со строками. Поэтому могу довериться автоматике/маршалингу. Если объявлю ReadFile/WriteFile как Unicode -буду передавать Unicode-строки, если ANSI -то ANSI. главное чтоб одинаково для Read и Write. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.02.2015, 14:16 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
Дмитрий773) WriteFile и ReadFile декларированы как ANSI т.е. (...ByVal lpBuffer As String) ну не надо буфер как строку передавать- передавай байты. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.02.2015, 14:20 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
Дмитрий77Но остается тогда нерешенной следующая задача: Предположим есть exe, есть mailslot. Одно приложение шлет в него ANSI (C++, только EN, переписывать/перекомпилировать на Unicode не буду). Другое приложение шлет в него Unicode. Как извернуться (с единственным mailslot)? Объясню почему я вспомнил про StreamWriter/Reader. Потому что mailslot -по сути файл с операциями записи чтения в него. В StreamWriter/Reader есть параметр Encoder, применяя который можно задать BOM (явное указание UTF8 например). Т.е. нельзя ли эту автоматику как то присобачить? Раз ты контролиуешь обе стороны обмена, то можно. При наличии ВОМ класс StreamReader игнорирует переданную ему кодировку и использует кодировку указанную через BOM. Сам массив данных можно трактовать как поток с помощью MemoryStream. Передавать при этом мы будем всегда массив байтов. Код фукнций подготовки данных и их чтения на стороне .NEТ можно организовать примерно так: Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12.
... |
|||
:
Нравится:
Не нравится:
|
|||
10.02.2015, 14:49 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
Изопропилну не надо буфер как строку передавать- передавай байты. А что это даст кроме гимора с конвертацией в байты и обратно? Я ж все равно не угадаю юникодные это байты или ANSI (если мне приходят "наборы двух типов", а чтобы понять от кого пришло надо прочесть чего там написано, а не зная ANSI или Unicode и не прочтешь, если только собственные "байт-метки" ставить, но это уже маразм). По хорошему декларировать все как Юникод (As String) и все типа в шоколаде. Это если не выходя за пределы .Net. Это я сделаю, это работает. Но что тогда делать с C++ которое отправляет и принимает ANSI. Причем сам C++ проект -чистое ANSI и Юникод там нафиг не нужен (для всего проекта). Код там такой: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42.
Вот как эти две "функции" переписать на прием/отправку именно Юникода? При том что весь проект в ANSI. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.02.2015, 15:22 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
bazile, т.е. я правильно понимаю, что при отправке юникод сообщения(UTF-8) я BOM добавляю в начало КАЖДОГО сообщения (массива байтов) - т.е на этапе формирования именно массива байтов? Соответственно если надо отправить в ANSI, то делаю массив с кодировкой .Default? А на обратном пути автоматика на основании наличия/отсутствия BOM? При этом конечно ReadFile/WriteFile декларирую однозначно с массивом байтов (IntPtr, надо смотреть) - инвариантно для обоих случаев - как в оригинале. Ну по крайне мере чутье не обмануло. Хотя я имел ввиду запись BOM в MailSlot (интерпретируя его как файл). Идея дошла. Спасибо. Пошел делать тест-проект, играться и переписывать свои ф-ции. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.02.2015, 15:41 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
Дмитрий77т.е. я правильно понимаю, что при отправке юникод сообщения(UTF-8) я BOM добавляю в начало КАЖДОГО сообщения (массива байтов) - т.е на этапе формирования именно массива байтов? Соответственно если надо отправить в ANSI, то делаю массив с кодировкой .Default? А на обратном пути автоматика на основании наличия/отсутствия BOM? Да. Дмитрий77Хотя я имел ввиду запись BOM в MailSlot (интерпретируя его как файл). Никто не мешает тебе написать класс MailSlotStream инкапсулирующий всю эту логику. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.02.2015, 16:02 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
bazileДмитрий77Хотя я имел ввиду запись BOM в MailSlot (интерпретируя его как файл). Никто не мешает тебе написать класс MailSlotStream инкапсулирующий всю эту логику. Не-не, здесь нет никакой здравой логики. Я то хотел по hMailSlotHandle открыть его как файл и использовать StreamWriter/Reader, ВМЕСТО ReadFile/WriteFile , возможно частично сделать что-то здесь можно, например указав "\\.\mailslot\MailSlotMyName" в качестве пути к файлу (на запись возможно да, если атрибуты - аналог CreateFile подберу), но я сомневаюсь что что-то путное выйдет. Короче счас попробую твою идею с подготовкой/чтением массива байтов + родные ReadFile/WriteFile. А уж потом посмотрю можно ли ему сообщение послать чисто через StreamWriter. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.02.2015, 16:24 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
Дмитрий77его как файл и использовать StreamWriter/Reader, ВМЕСТО ReadFile/WriteFile , это НИКАК не влияет на решение задачи ( кодировку текста) ... |
|||
:
Нравится:
Не нравится:
|
|||
10.02.2015, 16:48 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
Дмитрий77Не-не, здесь нет никакой здравой логики. "Спасибо" за высокую оценку. В моем понимании это наоборот прекрасно укладывается в .NET логику. Ты хочешь работать с mailslot через StreamWriter который умеет оборачиваться вокруг другого потока. Т.к. в нет класса наследника Stream который умеет работать с MailSlot, то значит можно написать свой класс для этой задачи. Дмитрий77Я то хотел по hMailSlotHandle открыть его как файл и использовать StreamWriter/Reader, ВМЕСТО ReadFile/WriteFile Конструктор FileStream позволяет передать дескриптор уже открытого потока. Затем FileStream можно передать StreamWriter/Reader. Попробуй так. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.02.2015, 17:23 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
bazile Код: vbnet 1. 2. 3. 4.
Так не хочет BOM к массиву пре-приписывать. Вроде вот так получается (до конца еще не доделал): Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8.
Проще нельзя этот BOM приписать? ... |
|||
:
Нравится:
Не нравится:
|
|||
10.02.2015, 18:10 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
Дмитрий77Проще нельзя этот BOM приписать? можно ... |
|||
:
Нравится:
Не нравится:
|
|||
10.02.2015, 18:57 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
ИзопропилДмитрий77Проще нельзя этот BOM приписать? можно Ты вот это имел ввиду? Код: vbnet 1. 2.
Это на .Net2 не фурычит, а я как ты возможно помнишь не рискну отказываться хотя бы от совместимости кода. Или что-то другое имелось в виду? ... |
|||
:
Нравится:
Не нравится:
|
|||
10.02.2015, 19:56 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
Ну вот вроде допилил, все типа работает: Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126. 127. 128. 129. 130. 131. 132. 133. 134. 135. 136. 137. 138. 139. 140. 141. 142. 143. 144. 145. 146. 147. 148. 149. 150. 151. 152. 153. 154. 155. 156. 157. 158. 159. 160. 161. 162. 163. 164. 165. 166. 167. 168. 169. 170. 171. 172. 173. 174. 175. 176. 177. 178. 179. 180. 181. 182. 183. 184. 185. 186. 187. 188. 189. 190. 191. 192. 193. 194. 195. 196.
Bazile, спасибо. bazileКонструктор FileStream позволяет передать дескриптор уже открытого потока. Затем FileStream можно передать StreamWriter/Reader. Попробуй так. Там все методы с Intptr первым параметром "устаревшие" (компилятор подчеркивает). Я попробовал интереса ради. Типа через задницу работает (отправка), но при этом вместо одного сообщения отправляется 2, первое пустое, а нужное приходит с задержкой в несколько секунд, уж не знаю чего там эта муть делает. При попытке подсунуть имя mailslot-а в FileStream или StreamWriter всегда имеем: Дополнительные сведения: FileStream не открывает устройства Win32, такие как логические диски и ленточные накопители. Избегайте использования "\\.\" в пути. Через API WriteFile/ReadFile все работает как и положено четко. Данный совет приписывать BOM к массиву байтов озвученную проблему "автоматики при приеме" решил. ==== По mailslot у меня один наверно вопрос еще. Я использую таймер который запускает ф-цию ReadApplyMessages_MailSlot() раз в секунду (в коде формы, код под спойлером). Т.е. время ожидания и обработки сообщения может затянуться (максимум на 1 секунду). В принципе для моих целей это приемлимо, но все же. В VB6 к сожалению с многопоточностью хреново. По хорошему это надо крутить циклом в отдельном потоке. Не подскажете как в .Net лучше сделать? Есть еще опасения что при выполнении команд буду нарываться на ошибки типа "вы пытаетесь дорваться до чего-то что было создано в другом потоке", посему особо не горю желанием такие штуки сгоряча и без опыта имплементировать. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.02.2015, 21:56 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
Дмитрий77Или что-то другое имелось в виду? да Код: c# 1. 2. 3. 4. 5. 6. 7. 8.
... |
|||
:
Нравится:
Не нравится:
|
|||
11.02.2015, 00:17 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
Дмитрий77Есть еще опасения что при выполнении команд буду нарываться на ошибки типа "вы пытаетесь дорваться до чего-то что было создано в другом потоке" настоящий программист документацию не читает ... |
|||
:
Нравится:
Не нравится:
|
|||
11.02.2015, 00:21 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
ИзопропилДмитрий77Или что-то другое имелось в виду?да Код: c# 1. 2. 3. 4. 5. 6. 7. 8.
Уже подумал о том что MemoryStream можно использовать обратно с StreamWriter (по аналогии с распаковкой в строку). Спасибо за код. Тогда лучше думаю так: Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8.
Иначе придется обрезать лишнее: Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
ИзопропилДмитрий77Есть еще опасения что при выполнении команд буду нарываться на ошибки типа "вы пытаетесь дорваться до чего-то что было создано в другом потоке" настоящий программист документацию не читает По MailSlot я документацию читал и примеры смотрел. Иначе б этот вопрос не возник. Просто это делалось под VB6 и таймер был выбран как наиболее разумный способ чтения MailSlot (VB6 при создании потока через API крашит, поэтому научился обходиться без них). .Net документацию по потокам - нет, не читал пока. Насколько понимаю, тема не очень тривиальная и с ней надо разбираться отдельно. Так что пока оставлю ту логику что есть, вопрос снимаю. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.02.2015, 08:07 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
Вызов метода в UI потоке - control.Invoke - ничего сложного, код в форме от таймерного отличаться не будет Массив из memoryStream - не твой - просто скопируй нужное количество байтов в свой массив ... |
|||
:
Нравится:
Не нравится:
|
|||
11.02.2015, 08:18 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
ИзопропилМассив из memoryStream - не твой - просто скопируй нужное количество байтов в свой массив Ну. А разве buffer = mstream.ToArray() именно это и не делает в одну строчку? Просто все копирования mstream.GetBuffer() с учетом mstream.Length -оно ни чуть не менее муторней чем тупое сложение массивов System.Text.Encoding.UTF8.GetPreamble() и System.Text.Encoding.UTF8.GetBytes(sMessage) - изначальный вариант ИзопропилВызов метода в UI потоке - control.Invoke - ничего сложного, код в форме от таймерного отличаться не будет Что значит не будет? Получил я message, мне например надо: нажать кнопку на форме, выгрузить форму, поменять надпись на форме... выполнить какую нибудь public function из модуля, которая на эту форму ссылается и т.п. Это хорошо еще если я к этой форме только в режиме чтения обращаюсь, или просто какие-то левые дела в этом ново-потоке делаю. А в общем случае это надо переписывать код, с отработкой заново всех потенциальных глюков. Не, давай забьем пока эту тему. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.02.2015, 09:00 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
Дмитрий77Что значит не будет? Есть форме(контроле) метод. без разницы - из таймера Invoke делать или из другого потока. Нет никаких глюков. В UI потоке будет вызываться ... |
|||
:
Нравится:
Не нравится:
|
|||
11.02.2015, 10:28 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
Вроде вот с WM_COPYDATA сделал по аналогии: Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82.
Но у меня получилось только с Dim lpData As IntPtr + Marshal.AllocHGlobal + Marshal.FreeHGlobal А упрощенный вариант почему-то не работает. Код: vbnet 1. 2. 3. 4. 5. 6.
Собственно код: Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50.
Т.е. он работает, но если посылать сообщение своему окну. А если чужому, то lpData As Byte() в target не читается (ptr получает а содержимое отсутствует). Для сравнения Если писать Dim lpData As String, то работает (с оговоркой про ANSI/Unicode естественно) В Mailslot+ReadFile/WriteFile, ByVal lpBuffer As Byte() на ура прокатило без всяких IntPtr. Где напортачил в нижнем коде? М.б. <MarshalAs(UnmanagedType. ???> Dim lpData As Byte() какой нибудь надо подставить? ... |
|||
:
Нравится:
Не нравится:
|
|||
11.02.2015, 13:25 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
Дмитрий77, в маршале полезно указывать, какой параметр содержит длину и в каком направлении передаются данные ... |
|||
:
Нравится:
Не нравится:
|
|||
11.02.2015, 13:32 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
Изопропилкакой параметр содержит длину и в каком направлении передаются данные Это как? Ну, cbData в принципе содержит длину lpData , хотя честно говоря cbData -параметр на мой взгляд излишний (вспомогательный), т.е. если массив то его длина и так известна. В VB6, имея указатель, я тупо читал память до '\0' -символа например. Во всяком случае не-указание cbData (или указание неверного значения) к крашу посылателя не приведут и приниматель обычно может вытащить данные и без cbData. Пытаюсь вот читать: Маршалинг по умолчанию для массивов но чет не нахожу ответа. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.02.2015, 13:57 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
Короче так и не понял как Dim lpData As Byte() лечить, оставлю Dim lpData As IntPtr, собственно и в VB6 я всегда передавал именно указатель на первый элемент байт-массива Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23.
Кстати интереса ради. Апишная "W" (CharSet:=CharSet.Unicode) это не UTF8 (собственно это очевидно). Еще как понял В UTF8 EN-символ кодируется одним байтом, в "Unicode" все кодируется двумя байтами. А какой ".Net " -кодировке соответствует "W"? ===ИзопропилЕсть форме(контроле) метод. без разницы - из таймера Invoke делать или из другого потока. Нет никаких глюков. В UI потоке будет вызываться Расшифруешь? Слово "Invoke" мне пока мало о чем говорит. Из таймера я могу написать: Me.Text="My caption" Me.Function() А поток меня как я понимаю пошлет с такими претензиями. Или как вызвать этот замечательный "UI поток" ну скажем из Form_Load, чтоб из него все чего хошь можно сделать было? Простенький совсем пример можно? ... |
|||
:
Нравится:
Не нравится:
|
|||
11.02.2015, 16:52 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
Дмитрий77Простенький совсем пример можно? Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21.
Дмитрий77А какой ".Net " -кодировке соответствует "W"? что есть "соответсвует" ? как маршаллинг опишешь так и будет. символы и строки в .NET - UTF-16, что в байтовых массивах живёт - заботы приложения. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.02.2015, 19:05 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
ИзопропилДмитрий77А какой ".Net " -кодировке соответствует "W"? что есть "соответсвует" ? как маршаллинг опишешь так и будет. символы и строки в .NET - UTF-16, что в байтовых массивах живёт - заботы приложения. В смысле отправляем так (у меня только два варианта:(1) CharSet.Unicode и (2) CharSet.ANSI -набор из .UTF8, UTF7 здесь отсутствует): Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19.
Ну, вот так удалось принять без искажений: Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20.
Ну да, значит "W"=.Unicode=UTF-16 (как ты и сказал) -она значит и есть "классический Юникод". ... |
|||
:
Нравится:
Не нравится:
|
|||
11.02.2015, 21:58 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
ИзопропилДмитрий77Простенький совсем пример можно?... Не понимаю мысли. Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19.
А где тут другой поток? InvokeВыполняет указанный делегат в том потоке, которому принадлежит основной дескриптор окна элемента управления, с указанным списком аргументов. Нажал на кнопку. Время в шапке тикает, а форма сдохла -ни подвинуть, ни закрыть. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.02.2015, 22:58 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
Дмитрий77А где тут другой поток? без разницы откуда звать DoIt - из UI потока или любого другого бесконечный цикл в процедуре ui - так нельзя, ui вызывается из цикла обработки сообщений, пока не выйдешь из процедуры ui - окно не получит никаких сообщений ... |
|||
:
Нравится:
Не нравится:
|
|||
11.02.2015, 23:17 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
Изопропил, кажется дошло. Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31.
Ну, т.е. для случая mailslot я кручу цикл чтения сообщения в ThreadFunction. Наверно не тупо Do...Loop а там параметры есть в MailSlot API на бесконечное ожидание нового сообщения. По получении message я стучу в ui-ф-цию, например передавая это самое msg в нее в качестве parameter as string Ну а ui уже занимается обработкой, имея доступ ко всем элементам формы. Так? Изопропилui вызывается из цикла обработки сообщений , пока не выйдешь из процедуры ui - окно не получит никаких сообщений В принципе тогда я могу получить то же самое и без .Net конструкции Delegate+Invoke Я могу послать "самому себе" SendMessage (Me.handle, WM_COPYDATA, 0, <parameter as string>) и обработать parameter в основной WndProc. Так ведь? Почему я стал отказываться от WM_COPYDATA (ее преимущество, что она стучится в окно "как только так сразу") в пользу mailslot: 1) Потому что обработка WM_COPYDATA "блокирует" вызывающую сторону (приложение) на время обработки сообщения на принимающей стороне. 2) Потому что нельзя слать WM_COPYDATA между разными User-аккаунтами (например сервис System не может послать сообщение в User окно и наоборот), у mailslot этого недостатка нет. А в комбинации Mailslot+Thread+(Delegate+Invoke) либо Mailslot+Thread+(WM_COPYDATA своему окну) вроде как при преимуществах mailslot решается вопрос с "получил как только так сразу". Не, ну наверно раз в .Net то лучше уж первое. Вроде все красиво. ... |
|||
:
Нравится:
Не нравится:
|
|||
12.02.2015, 12:04 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
Дмитрий77, используйте Task'и, это удобнее и практичнее ... |
|||
:
Нравится:
Не нравится:
|
|||
12.02.2015, 12:07 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
Roman Mejtesиспользуйте Task'и, Не рассматриваю, оно кажется с .Net 2 не совместимо. Да Thread думаю нормально. Счас попробую с MailSlot-Read процедурой потестить. Вопрос: myThread.Abort() в Form_Closed достаточно, чтоб поток "под занавес" не "нагадил"? ... |
|||
:
Нравится:
Не нравится:
|
|||
12.02.2015, 13:20 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
Дмитрий77В принципе тогда я могу получить то же самое и без .Net конструкции Delegate+Invoke Я могу послать "самому себе" SendMessage (Me.handle, WM_COPYDATA, 0, <parameter as string>) и обработать parameter в основной WndProc. Так ведь? ну не сенд, а post Зачем тебе .net ? Бери в руки с++ иначе будешь трахать мозг себе и людям бесконечно ... |
|||
:
Нравится:
Не нравится:
|
|||
12.02.2015, 13:21 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
Дмитрий77myThread.Abort() за такое завершение потока нужно больно бить по рукам. ... |
|||
:
Нравится:
Не нравится:
|
|||
12.02.2015, 13:22 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
Изопропилну не сенд, а post post с WM_COPYDATA не работает, обсуждалось много где неоднократно. Передаваемая структура (обсуждавшийся выше массив байтов) убьется раньше чем принимающая сторона ее прочтет. По этой же причине As Byte() наверняка и не работает. Я думаю предложенное тобой Delegate+Invoke здесь оптимально, поэтому WM_COPYDATA можно не обсуждать. Просто не сразу врубился в твой пример в том виде как ты его написал. ИзопропилДмитрий77myThread.Abort() за такое завершение потока нужно больно бить по рукам. Бить не надо, лучше объясни. Как его завершить в моем примере? Если ничего не сделать, то он продолжит Invok-ать в закрытую форму, что вызовет ошибку при закрытии формы. А метода типа .Stop() я не вижу. ... |
|||
:
Нравится:
Не нравится:
|
|||
12.02.2015, 13:32 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
Дмитрий77, создать флаг, при котором цикл завершится. Наверное так. ... |
|||
:
Нравится:
Не нравится:
|
|||
12.02.2015, 13:45 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
Дмитрий77, поток должен ждать какого либо события чтобы завершиться штатно. на худой конец может в случае отсутствия работы засыпать на какое-то время( например в ожидании завершения асинхронной операции с заданным таймаутом), пробудившись проверять флаг запроса завершения ... |
|||
:
Нравится:
Не нравится:
|
|||
12.02.2015, 13:47 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
Ну вот, подправил логику чтения из Mailslot с учетом обсуждаемого: Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68.
Вроде все отлично, стреляет "как только получено". Но вы пишете. Изопропилза такое завершение потока нужно больно бить по рукам ... поток должен ждать какого либо события Roman Mejtesсоздать флаг, при котором цикл завершится У меня нет "бесконечно долбящего" цикла, у меня поток висит на функции ReadFile, а висит она за счет MAILSLOT_WAIT_FOREVER при создании MailSlot. И вот куда мне этот "флаг" (для корректного выхода из цикла в MailSlotThreadFunction и завершения потока) втыкать? Ну если только закрыть MailSlot до закрытия потока и это сгенерирует какую-нибудь спецошибку в ReadFile ,которую я верну через MailSlotReadFirstInfinite и выйду из цикла. Но это надо играться. ... |
|||
:
Нравится:
Не нравится:
|
|||
12.02.2015, 16:04 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
Дмитрий77Ну если только закрыть MailSlot до закрытия потока и это сгенерирует какую-нибудь спецошибку в ReadFile ,которую я верну через MailSlotReadFirstInfinite и выйду из цикла. Но это надо играться. Ну вообще вот так наверно достаточно: Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15.
Происходит следующее: При выполнении CloseHandle(hMailSlotHandle) ReadFile находящийся в режиме бесконечного ожидания выходит с ошибкой ERROR_HANDLE_EOF (38) Моя MailSlotReadFirstInfinite возвращает False (номер ошибки думаю можно даже не отслеживать) По этому False я выхожу из цикла -> поток завершается Исключения за счет незакрытого потока не возникает. Вариант? ... |
|||
:
Нравится:
Не нравится:
|
|||
12.02.2015, 16:20 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
Дмитрий77У меня нет "бесконечно долбящего" цикла, у меня поток висит на функции ReadFile, а висит она за счет MAILSLOT_WAIT_FOREVER при создании MailSlot. а нужно с таймаутом висеть и по прошествии таймаута флаг проверять - далее чтение в цикле ... |
|||
:
Нравится:
Не нравится:
|
|||
12.02.2015, 18:09 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
Дмитрий77Вариант? да ... |
|||
:
Нравится:
Не нравится:
|
|||
12.02.2015, 18:10 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
ИзопропилДмитрий77У меня нет "бесконечно долбящего" цикла, у меня поток висит на функции ReadFile, а висит она за счет MAILSLOT_WAIT_FOREVER при создании MailSlot. а нужно с таймаутом висеть и по прошествии таймаута флаг проверять - далее чтение в цикле Какая разница? С таймаутом или бесконечно. Хотя конечно с учетом выхода по ERROR_HANDLE_EOF разница есть: флаг сразу сработает. Только он не нужен если я отслеживаю error. ИзопропилДмитрий77Вариант? да Ну вот на этом и остановимся. Имплементировал в проект, все отлично работает. Кстати в проекте без отработки выхода по ошибке форма закрывается, а прога остается висеть (без крашей) - потому что я не в саму форму "стучу", а в public ф-цию модуля. Так или иначе поток надо закрывать. ... |
|||
:
Нравится:
Не нравится:
|
|||
12.02.2015, 18:26 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
Дмитрий77Какая разница? С таймаутом или бесконечно завершение работы потока закрытием хэндла - частный случай. ... |
|||
:
Нравится:
Не нравится:
|
|||
12.02.2015, 19:49 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
Изопропилзавершение работы потока закрытием хэндла - частный случай. Ну, главное что для этого случая все отлично работает. Будут другие случаи, буду смотреть. Но во всех случаях когда в цикле разумно делать тупое засыпание через Sleep(N ms), я предпочту обычный таймер, нежели городить огород с потоком. В данном случае я выигрываю в пользу "как только так сразу", из-за этого таймер с MailSlot-ом таки напрягал, хотя я и читал Messag-ы блоками, т.е. не по одному раз в секунду а все имеющиеся не позже чем через секунду. Напрягают обычно 2 вещи: 1) подвисание UI потока (программа занята длительной операцией) 2) тупой должбеж чего-либо в надежде получить что-нибудь чего может долгое время не быть вообще (проверка таймером или какой нибудь цикл пусть бы и с DoEvent()). Да и в отдельном потоке такое делать - не фонтан. ... |
|||
:
Нравится:
Не нравится:
|
|||
12.02.2015, 20:37 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
Дмитрий77Да и в отдельном потоке такое делать - не фонтан. конечно не фонтан - на то и существуют события, асинхронный ввод-вывод, порты завершения, и т д ... |
|||
:
Нравится:
Не нравится:
|
|||
12.02.2015, 21:01 |
|
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
|
|||
---|---|---|---|
#18+
Дмитрий77Напрягают обычно 2 вещи: 1) подвисание UI потока (программа занята длительной операцией) операции запускать асинхронно, при невозможности - в отдельном потоке. в UI потоке - только рисование PS что характерно воевать с дотнетом нет никакого желания ... |
|||
:
Нравится:
Не нравится:
|
|||
12.02.2015, 21:06 |
|
|
start [/forum/topic.php?all=1&fid=20&tid=1401915]: |
0ms |
get settings: |
8ms |
get forum list: |
11ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
155ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
72ms |
get tp. blocked users: |
1ms |
others: | 14ms |
total: | 278ms |
0 / 0 |