|
|
|
Не выходит сделать прослойку между IStream и IStream: Access violation.
|
|||
|---|---|---|---|
|
#18+
Понадобилось сделать "прослойку" между IStream и IStream. Применений планируется много разных, но в качестве минимального тестирования - пытаюсь засунуть в GDI+. Лезут ошибки от AV 00300308 до AV 00000000 и AV 00000001... Не мог понять в чём дело, подумал, выкинул весь собственный функционал "прослойки" оставил лишь "базу" - а фик, всё равно падает. Подскажите пожалуйста, что же ему не так? Я ж уже всё выкинул и сейчас уже просто перенаправляю вызовы, откуда там взяться AV?: Проверка прослойки Код: pascal 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. Прослойка Код: pascal 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. Кстати зачем они задекларировали кучу параметров как "out"? Туда же передаётся указатель, и довольно часто передаётся NULL. Ни я не могу нормально NULL передать, ни нормально проверить что мне передали NULL... Нафига вот NULLABLE параметр декларировать через "out"? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2018, 11:10 |
|
||
|
Не выходит сделать прослойку между IStream и IStream: Access violation.
|
|||
|---|---|---|---|
|
#18+
SoulStreamПонадобилось сделать "прослойку" между IStream и IStream.Зачем? SoulStream . Нафига вот NULLABLE параметр декларировать через "out"? Это вопрос к эмбаркадере, которая так проимпортила заголовки SoulStream Ни я не могу нормально NULL передать, Код: pascal 1. SoulStream ни нормально проверить что мне передали NULL Код: pascal 1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2018, 12:41 |
|
||
|
Не выходит сделать прослойку между IStream и IStream: Access violation.
|
|||
|---|---|---|---|
|
#18+
Получаем IStream от какой-нибудь библиотеки/объекта и нам надо передать информацию из этого IStream в другую библиотеку/объект (тоже принимающие IStream), но с некоторыми модификациями. И ещё столкнулись с ситуациями, что данный нам IStream может не иметь реализаций для CopyTo/Clone и прочих - возвращает STG_E_UNIMPLEMENTEDFUNCTION и всё тут. Но какая разница зачем, я же сейчас убрал все свои модификации - почему не рабоатет даже простое перенаправление?? Наверное это я не учёл какой-то нюанс, но какой? Кто-то может направить? to _Vasilisk_ Не только к Эмбаркадере, Лазарус/FPC туда же, даже JEDI. Понятно что вопрос к ним, а я просто возмущаюсь)) Интересно что форумчане думают на этот счёт. Ну и вдруг разработчики прочитают меня и пересморят. _Vasilisk_ Код: pascal 1. _Vasilisk_ Код: pascal 1. Не-а. Во-первых выглядит тоже хреново. Во-вторых так как раз не работает: DelphiE2033 Types of actual and formal var parameters must be identicalLazarusError: Call by var for arg no. 3 has to match exactly: Got "untyped" expected "...."Приходится вот так: Код: pascal 1. или так: Код: pascal 1. ...или ещё как... И в разных местах приходится писать по-разному... Выглядит ваще коряво. И вообще есть мнение что если в коде используется символ ^ то код скорее всего "не очень хороший". В описании типа данных символ ^ - это нормально. Но не в самом исполняемом коде. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2018, 13:47 |
|
||
|
Не выходит сделать прослойку между IStream и IStream: Access violation.
|
|||
|---|---|---|---|
|
#18+
SoulStreamВо-вторых так как раз не работает:Я имел в виду, что вместо Pointer нужно подставить указатель на тот тип, который требуется SoulStreamНаверное это я не учёл какой-то нюанс, но какой?Только, что заметил, что вы сделали. Запомните НИКОГДА не смешивайте работу с классовыми и интерфейсными объектами. Если у вас есть объект, то вы работаете с ним или только как с классом, или только как с интерфейсом (смешивать можно, но нужно четко понимать, что вы делаете и что при этом происходит). Вот так все будет работать Код: pascal 1. 2. 3. 4. 5. И еще, если не хотите, чтобы вас били, а хотели бы, чтобы вас понимали - придерживайтесь стандартных правил именования. Имена классов начинаются с T, а интерфейсов с I. Так, что в срочном порядке переименуйте ваш класс в Код: pascal 1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2018, 14:17 |
|
||
|
Не выходит сделать прослойку между IStream и IStream: Access violation.
|
|||
|---|---|---|---|
|
#18+
SoulStream, У тебя OrigStream становится nil. Ты где-то либо стек портишь. У тебя обнуляется Wrapper, вызывается конструктор, с муссором по RefCount, а после вызываются операции с интерфейсом, которые приводят к AV. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2018, 14:24 |
|
||
|
Не выходит сделать прослойку между IStream и IStream: Access violation.
|
|||
|---|---|---|---|
|
#18+
ziv-2014У тебя OrigStream становится nil. Ты где-то либо стек портишь.У него после первого же SoulStream Код: pascal 1. 2. уничтожается Wrapper, потому, что это у него объектная ссылка ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2018, 14:28 |
|
||
|
Не выходит сделать прослойку между IStream и IStream: Access violation.
|
|||
|---|---|---|---|
|
#18+
_Vasilisk_, Ага заметил, так не стоит делать, из-за этого вся боль :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2018, 14:33 |
|
||
|
Не выходит сделать прослойку между IStream и IStream: Access violation.
|
|||
|---|---|---|---|
|
#18+
У тебя OrigStream становится nil.ну... Я ставил проверку на Assigned, она не срабатывала. после первого же Не после первого же))) Мне надоело тыкать F8 и я прикрутил банальное логирование в TMemo: внутри GdipLoadImageFromStream() начинается работа с IStream и успевало вызвать методы аж 8 раз - ток потом вылетало. А вот до сравнения с "Ok" не доходило даже. Теперь он делает 20 вызовов и завершается успешно. Спасибо вам огромное! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.07.2018, 06:13 |
|
||
|
Не выходит сделать прослойку между IStream и IStream: Access violation.
|
|||
|---|---|---|---|
|
#18+
SoulStream, что бы все методы вручную не проксировать про Implements погугли PS: только с XE3 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.07.2018, 11:35 |
|
||
|
Не выходит сделать прослойку между IStream и IStream: Access violation.
|
|||
|---|---|---|---|
|
#18+
kealon(Ruslan)PS: только с XE3В 2006 уже работало. Но ему нужно именно, что переопределить методы ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.07.2018, 12:14 |
|
||
|
Не выходит сделать прослойку между IStream и IStream: Access violation.
|
|||
|---|---|---|---|
|
#18+
SoulStreamНе после первого же)))То, что память сама не затиралась после первого вызова - чистая случайность. Деструктор StreamWrapper вызывался сразу же ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.07.2018, 12:16 |
|
||
|
Не выходит сделать прослойку между IStream и IStream: Access violation.
|
|||
|---|---|---|---|
|
#18+
_Vasilisk_kealon(Ruslan)PS: только с XE3В 2006 уже работало. Но ему нужно именно, что переопределить методы правильно оно работает только с XE3, где-то была ветка с разбором ему там пару методов переопределить, а не все ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.07.2018, 12:34 |
|
||
|
Не выходит сделать прослойку между IStream и IStream: Access violation.
|
|||
|---|---|---|---|
|
#18+
kealon(Ruslan)где-то была ветка с разборомМоя это ветка была ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.07.2018, 15:38 |
|
||
|
Не выходит сделать прослойку между IStream и IStream: Access violation.
|
|||
|---|---|---|---|
|
#18+
_Vasilisk_, ну тогда тем более должен знать, что оно не работает нормально ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.07.2018, 15:56 |
|
||
|
Не выходит сделать прослойку между IStream и IStream: Access violation.
|
|||
|---|---|---|---|
|
#18+
Про чего погуглить? По одному слову как-то не особо выходит. И я так и не понял - "работает" или "не работает"?)) Делаю примерно так: Код: pascal 1. 2. 3. 4. 5. В Делфи работает, а вот в Лазарусе не работает. Компилируется с warning'ом и просто не фурычит, пришлось переделать так: Код: pascal 1. 2. 3. 4. 5. И так уже работает и там и там. Кто-то сможет пояснить почему..? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2018, 05:11 |
|
||
|
Не выходит сделать прослойку между IStream и IStream: Access violation.
|
|||
|---|---|---|---|
|
#18+
SoulStreamКто-то сможет пояснить почему..?Вам же говорили не смешивать работу с классами и интерфейсами. Вот этот код SoulStream Код: pascal 1. 2. 3. эквивалентен такому Код: pascal 1. 2. 3. 4. 5. 6. 7. по умолчанию WrapperObj.GetInterface возвращает Self. Но это поведение можно легко изменить. Вот этот код SoulStream Код: pascal 1. говорит: "я знаю, что Wrapper это объект класса TStreamWrapper. Компилятор, верь мне". Далее, если вы не угадали, что это тот объект, то все будет работать. Если не угадали, то получите маловразумительные исключения в произвольных местах кода. Delphi вам верит, а Лазарус выражает сомнения. Вот этот код SoulStream Код: pascal 1. эквивалентен такому Код: pascal 1. 2. 3. Т.е. оба варианта плохи. Что делать? Если вам у IStream нужны дополнительные методы/свойства, то нужно поступать так же, как с классами - писать наследника Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2018, 10:26 |
|
||
|
Не выходит сделать прослойку между IStream и IStream: Access violation.
|
|||
|---|---|---|---|
|
#18+
LazarusЕсли не угадали ... Но Лазарус говорит: Unit2.pas(Y,X) Warning: Class types "IStream" and "TStreamWrapper" are not relatedИ по факту как бы просто не выполняет "property SomeProperty write FField". При этом Делфи выполняет корректно. ну... Просто создавал-то я класс, только ссылка на него интерфейсная... не? Ясно, спасибо большое... kealon(Ruslan)что бы все методы вручную не проксировать про Implements погугли ... где-то была ветка с разборомИ всё же про что это? Какая ветка? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2018, 14:16 |
|
||
|
Не выходит сделать прослойку между IStream и IStream: Access violation.
|
|||
|---|---|---|---|
|
#18+
Но а если мне нужны ещё и поля? Там, Int64 например, Cardinal, WideString? Интерфейс же мне не позволяет поля. То есть я лишён возможности делать "property SomeProperty read/write FField", а придётся переписывать исключительно в виде объявления методов get/set во втором интерфейсе, а потом ещё и реализовывать их же уже в TStreamWrapper? :( гм... А что если я буду просто хранить обе ссылки?: Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. Это будет чем-то совсем плохо? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2018, 14:20 |
|
||
|
Не выходит сделать прослойку между IStream и IStream: Access violation.
|
|||
|---|---|---|---|
|
#18+
SoulStreamНо а если мне нужны ещё и поля?Поля вообще в любом классе должны объявляться как strict private. И иметь доступ только из класса. Нужен доступ снаружи - объявляйте свойство SoulStreamпридётся переписывать исключительно в виде объявления методов get/set во втором интерфейсе, а потом ещё и реализовывать их же уже в TStreamWrapper? :(И в чем проблема? SoulStreamА что если я буду просто хранить обе ссылки?:когда интерфейсная ссылка обнулит счетчик ссылок - объект уничтожится. Вы на это наступили в самом первом посту. Хорошо, вот вариант для ленивых Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. Этот вариант кривой до безобразия, но, по крайней мере, лучше чем хранение двух ссылок. Ну и при вызове метод GetObjectImpl из другой dll могут возникнуть проблемы. Т.е., по сути, это те же разложенные грабли. Правильный наследник самое верное решение ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2018, 15:09 |
|
||
|
Не выходит сделать прослойку между IStream и IStream: Access violation.
|
|||
|---|---|---|---|
|
#18+
SoulStreamКак ж мне не угадать - я же сам только что создал свой класс. :)Вы создали объект класса и запросили у него интерфейсную ссылку. Делфи вернула вам тот же указатель, Лазарус - другой SoulStreamИ всё же про что это? Какая ветка? http://www.sql.ru/forum/1165959/izmenilsya-sposob-vyzova-ekzemplyar-klassa-dlya-queryinterface ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2018, 15:14 |
|
||
|
Не выходит сделать прослойку между IStream и IStream: Access violation.
|
|||
|---|---|---|---|
|
#18+
_Vasilisk_когда интерфейсная ссылка обнулит счетчик ссылок - объект уничтожится.Это-то я уже понял, но если я буду хранить обе - то полагаю объект сам не обнулится, пока у меня всё ещё хранится интерфейсная? Это объектная перестанет быть валидной, когда я обнилю интерфейсную - но я же точно знаю, когда я буду это делать. Впрочем, я подумал и пришёл к мысли - а так ли нужен мне вообще property, почему просто не пользоваться методоми set/get (тем более что их всё равно не сделать private)? Чем-то будет отличаться это: Код: pascal 1. 2. 3. 4. 5. 6. от вот этого?: Код: pascal 1. 2. 3. 4. 5. 6. И ещё тут нашёл/прочитал - советуют всегда использовать safecall, и аргументируют мощно, надо подумать... С: ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2018, 23:17 |
|
||
|
Не выходит сделать прослойку между IStream и IStream: Access violation.
|
|||
|---|---|---|---|
|
#18+
SoulStreamЧем-то будет отличаться это:Тем, что QueryInterface(IStream) работать не будет. Попробуйте такой код с обоими вариантами Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. SoulStreamсоветуют всегда использовать safecallЭто для COM. Там правила жестче. Для внутренней реализации это не обязательно. И будет немного медленнее. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.07.2018, 14:28 |
|
||
|
Не выходит сделать прослойку между IStream и IStream: Access violation.
|
|||
|---|---|---|---|
|
#18+
SoulStreamЭто объектная перестанет быть валидной, когда я обнилю интерфейсную - но я же точно знаю, когда я буду это делать.Сейчас будете знать. А через месяц? Если уже делать гибрид, то не храните объектную ссылку вообще. А каждый раз запрашивайте у интерфейса. Оно безопаснее SoulStreamа так ли нужен мне вообще property, почему просто не пользоваться методоми set/getА какая разница? Тем более, что property можно не объявлять в классе. Достаточно их объявить в интерфейсе ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.07.2018, 14:31 |
|
||
|
Не выходит сделать прослойку между IStream и IStream: Access violation.
|
|||
|---|---|---|---|
|
#18+
SoulStreamkealon(Ruslan)что бы все методы вручную не проксировать про Implements погугли ... где-то была ветка с разборомИ всё же про что это? Какая ветка? 17876455 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.07.2018, 19:42 |
|
||
|
|

start [/forum/topic.php?fid=58&fpage=102&tid=2040634]: |
0ms |
get settings: |
7ms |
get forum list: |
19ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
53ms |
get topic data: |
9ms |
get forum data: |
3ms |
get page messages: |
61ms |
get tp. blocked users: |
1ms |
| others: | 228ms |
| total: | 387ms |

| 0 / 0 |
