|
|
|
2 варианта создания PSafeArray для маршаллинга - в чём разница?
|
|||
|---|---|---|---|
|
#18+
Есть библиотека типов вот с таким IDL (фрагмент): Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. В дельфи эта библиотека экспортируется вот так: Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. Реализация интерфейса ITestUser - внешняя (дотнетовская сборка, если это имеет значение), интерфейс ITest реализуется в дельфи. Если мы собираем PSafeArray как-то так: Код: 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. то всё отрабатывает нормально - внешний компонент через интерфейс получет данные, и нормально их разбирает. Но если мы собираем PSafeArray вот так (этот способ фигурирует во многих примерах и пособиях в интернете): Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. то внешний компонент на вызове ITest.GetData выбрасывает ошибку "SafeArray ранга 65262 передан в метод, которому требуется массив ранга 1". Пробовал пробежаться по результату второго варианта (в дельфи) - вроде всё в порядке, количество измерений какое нужно, размер требуемый, все данные на месте - но вот видимо всё же есть какая-то разница между первым способом и вторым, и она важна при маршаллинге внешнему компоненту. А вот в чём она, эта разница? Delphi 2010. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.06.2020, 10:12 |
|
||
|
2 варианта создания PSafeArray для маршаллинга - в чём разница?
|
|||
|---|---|---|---|
|
#18+
Серьёзно? Во втором варианте вы передаёте из функции указатель на память и тут же эту память освобождаете (Arr будет удалён до выхода из функции)! В каких-таких местах такой способ показан? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.06.2020, 11:36 |
|
||
|
2 варианта создания PSafeArray для маршаллинга - в чём разница?
|
|||
|---|---|---|---|
|
#18+
GunSmoker Серьёзно? Во втором варианте вы передаёте из функции указатель на память и тут же эту память освобождаете (Arr будет удалён до выхода из функции)! В каких-таких местах такой способ показан? Вот здесь, например . Плюс очень часто встречал такой способ, изучая исходник JclDotNet . Но в первом случае нюанс передачи данных куда-то вообще не играет роли, а во втором все внешние методы, в которые передаются данные, возвращают управление до выхода из метода, который формирует данные. А у меня фактически callback, и ситуацию с автоматической очисткой данных после выхода из метода я как-то упустил. Для второго варианта вынес Arr в поле класса - заработал и он. Теперь всё понятно, спасибо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.06.2020, 12:18 |
|
||
|
2 варианта создания PSafeArray для маршаллинга - в чём разница?
|
|||
|---|---|---|---|
|
#18+
Что-то вы не то делаете. Если вы используете первый вариант, то вызывающий поюзает массив и спокойно его удалит вызовом SafeArrayDestroy. По сути, здесь используется shared менеджер памяти, скрытый за фасадом SafeArrayXYZ функций. Если же вы используете второй вариант, то вызывающий никак не может удалить массив, ведь он хранится у вас в поле класса, доступа к которому у вызывающего нет. В указанных вами ссылках есть существенное отличие: в них права на владение массивом не отдаются во внешний код. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.06.2020, 13:58 |
|
||
|
2 варианта создания PSafeArray для маршаллинга - в чём разница?
|
|||
|---|---|---|---|
|
#18+
GunSmoker, Для второго способа я вынес вариантную переменную в поле только для проверки того, что маршаллинг пройдёт нормально, и сделал это только в тестовом наколеночном примере, чтобы окончательно разобраться. В рабочий код пошёл первый способ, с SafeArrayCreate. Про shared менеджер памяти я по пути примерно догадался сам, потому что тоже пытался указатель на PSafeArray сохранять в поле класса, и при повторном обращении к методу, если указатель инициализирован, вызывать SafeArrayDestroy - нарвался на EOlySysError: Memory is locked, посмотрел на счетчик блокировок экземпляра SafeArray, и увидев странное значение типа -123789, предположил, что его до меня уже зачистили. Убрал хранение указателя в поле и SafeArrayDestroy, и никаких заметных утечек памяти не обнаружил (поскольку это всё в рабочем коде используется для передачи достаточно больших объемов, утечки были бы очень заметны). Жаль, что литературу по этой теме сейчас трудно найти - хрестоматийную Inside COM Роджерсона я прочитал, но там такие нюансы не разъясняются. Всё остальное - оставшиеся обзорные статьи и MSDN, которые надо долго перелопачивать, чтобы узнать про вот этот же shared-менеджер. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.06.2020, 14:15 |
|
||
|
|

start [/forum/topic.php?fid=58&fpage=41&tid=2038185]: |
0ms |
get settings: |
7ms |
get forum list: |
25ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
44ms |
get topic data: |
14ms |
get forum data: |
3ms |
get page messages: |
56ms |
get tp. blocked users: |
2ms |
| others: | 229ms |
| total: | 388ms |

| 0 / 0 |
