Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Как вернуть через API массив структур? API эту сам пишу.
|
|||
|---|---|---|---|
|
#18+
Исходный код (мой) из которого пытаюсь родить нужную мне dll в соседнем топике: Получение нестандартных полей (телефон,факс) из Windows Contacts -диалог Select Recipients Ну или под спойлером (Юникод вариант я таки осилил): Код: 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. 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. В общем как-то так пока: Код: 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. Полный пока код функции под спойлером, но суть я в общем выделил выше: Код: 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. 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. Проблема в чем. Последний аргумент функции LPRECIPLIST FAR * lppRecipList это типа указатель на массив структур RECIPLIST. Размерность массива соответствует числу выбранных в диалоге адресной книги получателей, посему заранее (на вызывающей стороне) не известна. Функция также возвращает число этих самых элементов массива в return cEntries Пока с lppRecipList не стал играться все работало. Тест-Код на стороне VB.Net клиента такой: Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. Для начала хочу получить указатель на массив, т.е. PtrRecipList. Ошибка вылазит: .NetНеобработанное исключение типа "System.AccessViolationException" в WabTestNet.exe Дополнительные сведения: Попытка чтения или записи в защищенную память. Это часто свидетельствует о том, что другая память повреждена. Что я напортачил в C++? Предполагаю, что не выделил память под элементы массива. Внутри C кода мне известна размерность lppAdrList->cEntries И я потом начинаю заполнять элементы lppRecipList[i]->lpszDisplayName = lpProp->Value.lpszW; lppRecipList[i]->lpszEmailAddress = lpProp->Value.lpszW; Или где-то тупо ошибся в "грамматике", делал как бы по образу-подобию чего под руку подвернулось. В .Net предполагаю сначала получить указатель IntPtr на массив структур, потом воспользоваться Marshal.PtrToStructure (Ptr) сдвигая Ptr на размер структуры для получения след. элемента (количество функция возвратит) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2016, 06:49 |
|
||
|
Как вернуть через API массив структур? API эту сам пишу.
|
|||
|---|---|---|---|
|
#18+
Дмитрий77, размер нужно тоже возвращать. например, сделать еще один выходной параметр. (в функцию передать указатель на size_t, в функции под этому адресу записать значение) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2016, 10:42 |
|
||
|
Как вернуть через API массив структур? API эту сам пишу.
|
|||
|---|---|---|---|
|
#18+
MasterZiv, детальнее в эту хрень не волновался, извини... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2016, 10:44 |
|
||
|
Как вернуть через API массив структур? API эту сам пишу.
|
|||
|---|---|---|---|
|
#18+
MasterZivразмер нужно тоже возвращать.) Так именно его я возвращаю. 0- если элементов нет или к-во элементов если они есть. Но к-во элементов в массиве становится известно только внутри самой ф-ции. MasterZiv (в функцию передать указатель на size_t, в функции под этому адресу записать значение) Ну так я и передаю указатель ByRef LPRECIPLIST FAR * lppRecipList. По идее ф-ция должна в этом параметре вернуть указатель, и по этому указателю записать массив. При этом наверно выделить нужную память перед тем как писать. И вот как это сделать? А освобождать эту память видимо надо уже в вызывающем приложении после прочтения массива. Зарезервировать память по указателю в вызывающем приложении и кинуть в ф-цию конкретный указатель я не могу, т.к. заранее не знаю сколько нужно памяти (к-во элементов в массиве становится известно только внутри самой ф-ции). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2016, 14:52 |
|
||
|
Как вернуть через API массив структур? API эту сам пишу.
|
|||
|---|---|---|---|
|
#18+
Хорошо, давайте по простому, а то слишком много кода привел: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. Вызов из клиента Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. ошибка на клиенте при вызове CPP_TestНеобработанное исключение типа "System.AccessViolationException" в WabTestNet.exe Дополнительные сведения: Попытка чтения или записи в защищенную память. Это часто свидетельствует о том, что другая память повреждена. Не, ну то что я делаю что-то сильно не так, это я понимаю. А как сделать так? Я хочу сделать по аналогии с MAPIAddress function Последний параметр _Out_ lpMapiRecipDesc *lppNewRecips lppNewRecips outPointer to an array of MapiRecipDesc structures containing the final list of recipients. This array is allocated by MAPIAddress, cannot be NULL, and must be freed using MAPIFreeBuffer, even if there are no new recipients. Чтобы можно было из клиента использовать код типа как здесь сделал: 18646419 (к сожалению у меня нет исходников ф-ции MAPIAddress чтобы посмотреть C-начинку как они этот чертов массив внутри API формируют). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2016, 16:11 |
|
||
|
Как вернуть через API массив структур? API эту сам пишу.
|
|||
|---|---|---|---|
|
#18+
Ну вот так вроде выводит: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. Но у меня .Net прога почему-то виснет. Выводит MsgBox(NewReceipts( 0 ).ulReceipType.ToString & " : " & NewReceipts( 0 ).lpszDisplayName.ToString & "<" & NewReceipts( 0 ).lpszEmailAddress.ToString & ">") и виснет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2016, 16:59 |
|
||
|
Как вернуть через API массив структур? API эту сам пишу.
|
|||
|---|---|---|---|
|
#18+
Дмитрий77Но у меня .Net прога почему-то виснет. Виснет из за Marshal.FreeCoTaskMem(PtrRecipList) Если убрать, то не виснет. Но тогда вопрос как освободить память захапанную на стороне C через malloc. И дальше, пытаюсь напр. выводить массив из 2-х элементов: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. Гадина рушится очевидно при попыке заполнения lppRecipList[1] (выделенные строчки) Как правильно память выделить под массив из 2-х или n элементов? (внутри c я размер знаю) Или надо как-то объяснить в коде что это именно массив и что там n элементов. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2016, 17:26 |
|
||
|
Как вернуть через API массив структур? API эту сам пишу.
|
|||
|---|---|---|---|
|
#18+
Дмитрий77на стороне C через malloc. ответ в вопросе - выделяй через CoTaskMemAlloc ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2016, 18:07 |
|
||
|
Как вернуть через API массив структур? API эту сам пишу.
|
|||
|---|---|---|---|
|
#18+
ИзопропилДмитрий77на стороне C через malloc. ответ в вопросе - выделяй через CoTaskMemAlloc За это спасибо. Если убрать malloc и сделать в C Код: plaintext 1. то на стороне .Net Код: vbnet 1. не приводит к висяку и надо думать вопрос высвобождения памяти таким образом решается Но что делать если элементов больше одного Вот этот код Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. безжалостно глючит Не хочет понимать что lppRecipList это массив из двух элементов и под него выделена память под два элемента. Если убрать заполнение lppRecipList[1] то не глючит. Но я то массив хочу вернуть, а размер задать внутри ф-ции. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2016, 18:37 |
|
||
|
Как вернуть через API массив структур? API эту сам пишу.
|
|||
|---|---|---|---|
|
#18+
Дмитрий77безжалостно глючит содержательная диагностика ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2016, 19:01 |
|
||
|
Как вернуть через API массив структур? API эту сам пишу.
|
|||
|---|---|---|---|
|
#18+
Дмитрий77, размеры структур сравни в с++ и бейсик коде. выравнивание может быть разным ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2016, 19:08 |
|
||
|
Как вернуть через API массив структур? API эту сам пишу.
|
|||
|---|---|---|---|
|
#18+
ИзопропилДмитрий77безжалостно глючит содержательная диагностика Я писал выше ошибку в .Net. авторНеобработанное исключение типа "System.AccessViolationException" в WabTestNet.exe Дополнительные сведения: Попытка чтения или записи в защищенную память. Это часто свидетельствует о том, что другая память повреждена. И происходит она до того как ф-ция чего-то возвращает. Ошибка очевидно в C-коде при заполнении элемента массива отличного от первого, я выделил строчки в коде. Сказать какая с т. зр. C не могу, это dll, компилируется нормально. Я думаю человек пишущий на C сразу поймет, но я то оч. редко к C обращаюсь. Изопропилразмеры структур сравни в с++ и бейсик коде. выравнивание может быть разным 12 и там и там. Две строки и число по 4 байта на элемент структуры. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2016, 20:52 |
|
||
|
Как вернуть через API массив структур? API эту сам пишу.
|
|||
|---|---|---|---|
|
#18+
Не получается у меня больше одного элемента вернуть. Неужели такая сложная задача Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. Ну что тут может быть не так? Все уже перепробовал, как гуглить эти вещи не знаю. Почему не пишет второй элемент lppRecipList[1]? Не, могу наверно все данные в одну строку "распечатать" и вернуть, а потом сидеть как дебил в бейсике парсить километровую строку (результат можно достичь и гавнокодом), но хотелось бы по нормальному. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2016, 00:19 |
|
||
|
Как вернуть через API массив структур? API эту сам пишу.
|
|||
|---|---|---|---|
|
#18+
Дмитрий77, попробуй памяти выделить с запасом, в отладчике посмотри что происходит ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2016, 00:49 |
|
||
|
Как вернуть через API массив структур? API эту сам пишу.
|
|||
|---|---|---|---|
|
#18+
Изопропилпопробуй памяти выделить с запасом, Это не помогает. Так написал: Код: plaintext 1. Куда больше? А вылетает точно также на заполнении второго элемента. Там что-то другое. Просто C ни хрена не знаю, навыка нет, но иногда надо, вот и мучаюсь. Я вот думаю, у меня в структуре строки. Размер 12 байтов, 4 байта на строку. Но 4 байта это указатель на массив байтов, где эта строка сидит. Когда я память выделяю, я ее выделяю под указатель на массив байтов а не под сам этот массив. Где гарантия что там все корректно будет? Не не то, с одним элементом же корректно работает. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2016, 01:20 |
|
||
|
Как вернуть через API массив структур? API эту сам пишу.
|
|||
|---|---|---|---|
|
#18+
Как мне хотя б массив строк вывести? Пытаюсь так: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. Достаю так (ну хоть как то): Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. В последних трех словах из примера первая буква теряется. Это дурдом какой-то. Как мне через API вывести набор? Имя тип адресата телефон факс количество этих выборок и все данные мне внутри C-кода доступны. Данные я получил. Вывести не могу. Длинные строки (5 строк с разделителями а потом парсить) я вернуть могу конечно, но в си объединение строк через всякие wsprintf это тоже задница буфер придется делать немеренный (а вдруг выборка на 20000 адресатов?) плохой вариант. Мне надо хотяб пять массивов строк, если не один массив структур. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2016, 08:26 |
|
||
|
Как вернуть через API массив структур? API эту сам пишу.
|
|||
|---|---|---|---|
|
#18+
Мне реальным только вариант в таком духе видится: Код: plaintext 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. Он работает, но это через одно место. Причем теоретически буфера в 100000 для строки тоже могут переполниться. Если считать что поле 20 символов, то 100000/20=5000 записей. Смотря какие цели. Если добавить 2 e-mail то это излишки, а если выборка из номеров телефонов, то может и не хватить. И думаю транжирство памяти, хорошо если не утекает. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2016, 08:50 |
|
||
|
Как вернуть через API массив структур? API эту сам пишу.
|
|||
|---|---|---|---|
|
#18+
Дмитрий77, воспроизвести ошибку никак не удалось, всё возвращается как положено какой фрагмент приведённого кода действующий, а какой мысли вслух - понять не могу лучше всего - приложи целиком проект с++ ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2016, 12:00 |
|
||
|
Как вернуть через API массив структур? API эту сам пишу.
|
|||
|---|---|---|---|
|
#18+
Дмитрий77, внимательно прочитал твои портянки, ошибочка простая. Причина - говнокод в качестве заготовкм в твоём коде - lppRecipList - трактуется не как указатель на массив структур, а массив указателей на структуры ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2016, 12:24 |
|
||
|
Как вернуть через API массив структур? API эту сам пишу.
|
|||
|---|---|---|---|
|
#18+
Изопропиллучше всего - приложи целиком проект с++ Лови. CPP_AddressBook -собственно ради чего все делается (вылетает при выборе 2-х и более адресатов) CPP_Test - попытка вернуть 2 элемента структуры (соответственно также вылетает) CPP_Test2- попытка вернуть массив просто строк (не вылетает и даже выводит, но не совсем правильно) Проект VC++2005EE, но конвертация в 2010 не спасает. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2016, 13:16 |
|
||
|
Как вернуть через API массив структур? API эту сам пишу.
|
|||
|---|---|---|---|
|
#18+
На всякий случай сопряженный VB.NET (2013) Пути в декларациях указаны абсолютные, надо менять на свои. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2016, 13:18 |
|
||
|
Как вернуть через API массив структур? API эту сам пишу.
|
|||
|---|---|---|---|
|
#18+
ИзопропилДмитрий77, внимательно прочитал твои портянки, ошибочка простая. Причина - ... в твоём коде - lppRecipList - трактуется не как указатель на массив структур, а массив указателей на структуры Ты лучше скажи как записать чтоб было правильно. Я на C вообще пишу очень редко и от этих звездочек справа слева честно крыша сразу съезжает. И очень хочется чтоб ты был прав, потому как измотался уж. Со строками, которые соединять а потом парсить - не вариант. Макс. буфера и длины строки хватает на 30 где-то контактов, потом Stack Overflow. Уже думал в файл результат написать, а потом из VB его прочесть. Но это уже ни в какие ворота (в рамках вызова одной ф-ции). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2016, 13:27 |
|
||
|
Как вернуть через API массив структур? API эту сам пишу.
|
|||
|---|---|---|---|
|
#18+
Дмитрий77, Код: plaintext 1. 2. PS а насчёт звёздочек - эт ты зря ) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2016, 13:48 |
|
||
|
Как вернуть через API массив структур? API эту сам пишу.
|
|||
|---|---|---|---|
|
#18+
Дмитрий77, память не забудь аккуратно почистить, лучше всего доверить это с++ коду ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2016, 13:56 |
|
||
|
Как вернуть через API массив структур? API эту сам пишу.
|
|||
|---|---|---|---|
|
#18+
ИзопропилДмитрий77, Код: plaintext 1. 2. Заработало, однако. До меня б никогда не доперло. Огромное спасибо. Изопропилпамять не забудь аккуратно почистить, лучше всего доверить это с++ коду С Код: plaintext 1. .Net Код: vbnet 1. Недостаточно? (на стороне C++ наверно не смогу, иначе затрется то что возвращаю) Ну, не считая естественно очистки структур в самих интерфейсах, где это указано в msdn, что действительно делается в си. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2016, 14:14 |
|
||
|
Как вернуть через API массив структур? API эту сам пишу.
|
|||
|---|---|---|---|
|
#18+
Дмитрий77Ну, не считая естественно очистки структур в самих интерфейсах, где это указано в msdn, что действительно делается в си. об этом и речь. напиши в dll дополнительную функцию для освобождения памяти, адрес и к-во передай, в ней и строчки освободи, и сам блок памяти. избавишь vn.net код от лишнего знания ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2016, 14:25 |
|
||
|
Как вернуть через API массив структур? API эту сам пишу.
|
|||
|---|---|---|---|
|
#18+
Изопропил, я другого пока не понимаю дописал типа код (на предмет телефонов), расширил структуру Код: 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. 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. И теперь оно стало глючить случайным образом (чем больше элементов, тем больше вероятность) но уже на стороне .Net (количество возвращает). Все пустые строки вроде забиваю "" вместо NULL. Код: 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. .NetВ среде выполнения обнаружена критическая ошибка. Ошибка произошла по адресу 0x73f59485 в потоке 0x11cc. Код ошибки 0xc0000005. Она может быть вызвана ошибкой в CLR или в небезопасных либо не поддающихся проверке фрагментах пользовательского кода. Обычно источниками таких ошибок бывают ошибки упаковки, допускаемые пользователями при COM-взаимодействии, либо PInvoke, повредивший стек. И мне очень не нравится выделенное место, где я плюсую указатель, вообще говоря в .Net2 такое вообще не пройдет, надо типа New IntPtr(ptr.toInt32/64 + дельта) но в .Net 4.5 прокатывает. такое ощущение что я местами промазываю мимо структуры Нет ли какого подвоха? Или другого приема? М.б. можно попробовать параллельно вернуть массив указателей на элементы и применять их а не один, который двигаю? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2016, 15:58 |
|
||
|
Как вернуть через API массив структур? API эту сам пишу.
|
|||
|---|---|---|---|
|
#18+
Перед глюком обычно начинает писать немного чуши (которой реально нет) Код: plaintext 1. 2. 3. Предполагаю что в какой-то момент в Debug.Print ловится NULL (которого по логике там быть не должно) и на этом вылетает. когда я делаю Код: plaintext 1. не получается, что там мог остаться мусор, который может "сыграть"? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2016, 16:11 |
|
||
|
Как вернуть через API массив структур? API эту сам пишу.
|
|||
|---|---|---|---|
|
#18+
Дмитрий77, преждевременное освобождение памяти lpWABObject->FreeBuffer(lpProps); ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2016, 16:41 |
|
||
|
Как вернуть через API массив структур? API эту сам пишу.
|
|||
|---|---|---|---|
|
#18+
Дмитрий77, копируй строки, а не ссылки проще создавать/освобождать SysAllocString/SysFreeString (BSTR внутри будут) освобождение памяти, как я уже и говорил, лучше сделать отдельным вызовом типа CPP_AddressBookFree(PtrRecipList,num) - и строки почистить и массив структур - всё в c++ коде, который точно знает что и как размещалось с пустыми строками - или NULL оставляй - в бейсике разберёшься, или SysAllocString("") делай. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2016, 16:52 |
|
||
|
Как вернуть через API массив структур? API эту сам пишу.
|
|||
|---|---|---|---|
|
#18+
авторИ теперь оно стало глючить случайным образом (чем больше элементов, тем больше вероятность) но уже на стороне .Net (количество возвращает). Все пустые строки вроде забиваю "" вместо NULL Вылечил заменой Код: plaintext 1. 2. 3. 4. на Код: plaintext 1. 2. 3. 4. 5. Крашить перестало. Но при этом глючки остались. При достаточно большом к-ве элементов. И исключительно в номерах телефонов и факсов (те поля которые выводятся через lpProps дополнительным кодом) - не везде но вполне стабильные: Код: xml 1. 2. 3. 4. 5. (*-ки мои, ???-вопросики-китайские крякозябры вместо набора цифр, не глючат только последние выводимые строки с телефонами) Глюки для фиксированной большой выборки достаточно стабильны ( одни и те же крякозябры) Ну да, это большой непорядок, именно по телефонам может делаться большая выборка. Изопропилпреждевременное освобождение памяти lpWABObject->FreeBuffer(lpProps); Не уверен, по крайней мере если закомментировать то те же глюки -крякозябры остаются. lpProps вычисляется каждый раз для заново для каждого контакта - дополнительное рытье на предмет телефонов. На самом деле не уверен что его надо грохать и именно через lpWABObject->FreeBuffer, эта ф-ция по мсдн должна грохать другой объект &lpWABObject возвращаемый "WabOpen". IMailUser::GetProps MethodlppPropArray SPropValue Address of a pointer to a variable of type SPropValue that receives the property values. The variable must be freed by the client. сказано размыто лишь, что "must be freed by the client" но не сказано чем именно. lpWABObject->FreeBuffer(lpProps); вято из одного из немногочисленных примеров что удалось найти и не уверен что с этим примером все эквивалентно. Еще где-то видел код где чел делал MapiFreeBuffer(lpProps), но мне кажется это другая опера и чел не прав. Да, я задумался. Что можно поменять? Есть идеи? Изопропилкопируй строки, а не ссылки проще создавать/освобождать SysAllocString/SysFreeString (BSTR внутри будут) Я знаю что ты любишь BSTR по очень старому топику(тоже делал dll). Если только в лоб покажешь как. Но честно не очень хочу, мне хватило утреннего маразма с * и скобками. И BSTR непонятно как с юникодом соотносится, там же другая ф-ция будет Marshal.ToBSTR ..кажется. Лучше б допонять как собычными виндовыми LPWSTR указателями допилить до ума. Тек. полный C-код на всякий случай под спойлером: Код: 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. 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. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2016, 23:06 |
|
||
|
Как вернуть через API массив структур? API эту сам пишу.
|
|||
|---|---|---|---|
|
#18+
Дмитрий77Не уверен, по крайней мере если закомментировать то те же глюки -крякозябры остаются. lpProps вычисляется каждый раз для заново для каждого контакта - дополнительное рытье на предмет телефонов. На самом деле не уверен что его надо грохать и именно через lpWABObject->FreeBuffer, эта ф-ция по мсдн должна грохать другой объект &lpWABObject возвращаемый "WabOpen". это не повод возвращать ссылки на освобождённую память, и без того граблей с этим древним API выше крыши (забавно, при создании этого API OleVariant был ещё неизвестен) никакой мистики в BSTR нет - указатель кажет на первый символ строки, длина - впереди, для чтения ничем не отличается от LPWSTR. С юникодом всё прозрачно, в конце концов - BSTR - это стандартные строки в COM и твоём любимом VB6 SysAllocString(строка) - просто создаёт копию строки Дмитрий77сказано размыто лишь, что "must be freed by the client" но не сказано чем именно. не освободишь - получишь утечку памяти. в WinAPI таких мутных мест много откуда контакты в примере - из локальной книги или из Active Directory? PS для начала отладь это хозяйство без dotnet, отладчиком посмотри как структуры заполняются. то что замена на globalalloc помогла, вызывает подозрение, что пишется где-то что-то мимо ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2016, 23:30 |
|
||
|
Как вернуть через API массив структур? API эту сам пишу.
|
|||
|---|---|---|---|
|
#18+
Изопропил, ИзопропилBSTR. Ну м.б. попробую но завтра если только (утро вечера мудренее). Я в той первой своей dll пробовал и вроде получалось, но остановился все же на возврате char *, почему именно не помню. ByRef там нигде не использовал, и там чистое ANSI было(прибамбас к AsProtect чисто EN , причем в .Net без dll с той кухней по определению вообще никак). Какую ф-цию использовать ты вроде сказал, хотя я эти вещи на лету не схватываю. [quot Изопропил]откуда контакты в примере - из локальной книги или из Active Directory? Папка "контакты" в Win 8.1, но конкретно этот набор был экспортирован однажды из OE6 (XP). С Active Directory (Win Server +Domen,) никогда не работал, и сервера тестирую только в режиме "рабочей группы", Domen пару раз делал давно, но глючно это, и без глюков назад уже не преобразуешь. ИзопропилPS для начала отладь это хозяйство без dotnet Легко сказать, хотелось бы хоть как то уже доделать и воспользоваться. Изопропилвызывает подозрение, что пишется где-то что-то мимо Какое-то понимание выше начального есть, но когда слишком задумываешься, крыша таки едет. Напр. выделяю память под структуру, строка - 4 байта-понятно, указатель, а сама строка по этому адресу насколько неприкосновенна.. все ...крыша поехала. Если честно, хочется сделать - главное чтоб работало, забыть и пользоваться. То что чуть-чуть чего-то теряется - не, стараюсь вовсю как правильно, но часто это не очень то и существенно. <Адресная книга> - по логике кнопка редко нажимаемая, лично мне нужна для нескольких настроек где надо выбрать мыло, и для окна отправки факса, где надо задать номер(а) факса - окно живущее мб. полминуты пока этот номер не выберут(а скорее всего просто напечатают) + пару параметров может быть (это не таймер который иконки генерит по 5 раз на секунду - классический пример когда я конкретно однажды накололся -через несколько часов все висло). При том что у меня в основном приложении своей адресной книги пока нет , идея думается не плоха, стандартна и посему правильная, м.б. ей и не будут пользоваться, но хорошее впечатление это производит. А вот крякозябры вместо номеров телефонов - это да, косяк практически ощущаемый. Из VB(6 или .Net) обычно на ура все делаю, рука набита, но не с интерфейсами. А в C вроде все еще проще, но прикладные моменты убивают наповал. Разные рантаймы с одной стороны (поэтому и делаю в 2005-й чтоб не связываться, подмечено/годами проверено что любой .Net >= 2.0 SP1 (и независимый 4.5 тоже) ставит нужный рантайм под эту 2005-ю сборку 50727 кажется, а этот .Net (2.0 SP1 для XP, 4.5 или выше для семерки/висты, на остальных по дефолту) я вместе с прогой при установке требую, т.е. не надо других дистрибюшенов), куча заумностей с теми же строками с другой стороны и т.п. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.01.2016, 01:04 |
|
||
|
Как вернуть через API массив структур? API эту сам пишу.
|
|||
|---|---|---|---|
|
#18+
Дмитрий77Если честно, хочется сделать - главное чтоб работало, забыть и пользоваться. память утечёт в коде как минимум двум интерфейсам не делается Release() если с освобождением памяти разобраться не удастся(ввиду кривой документации, в частности) - говнокод следует изолировать в отдельном процессе Дмитрий77Напр. выделяю память под структуру, строка - 4 байта-понятно, указатель, а сама строка по этому адресу насколько неприкосновенна.. все ...крыша поехала. получил строку - скопируй к себе - будешь уверен что преждевременно её никто не освободит и твоя ссылка не будет указывать в небо. Дмитрий77Из VB(6 или .Net) обычно на ура все делаю, рука набита, но не с интерфейсами. это основы COM - не разберёшься - будешь и дальше жрать кактус ЗЫ подождём пару дней ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.01.2016, 10:31 |
|
||
|
Как вернуть через API массив структур? API эту сам пишу.
|
|||
|---|---|---|---|
|
#18+
Изопропил, Ну смотри. Виновата действительно Код: plaintext 1. если убрать то все OK тогда уж видимо Код: plaintext 1. 2. проще убрать не уверен что оно здесь вообще надо в моем контексте IWABObject::FreeBuffer Method Frees memory allocated with IWABObject::AllocateBuffer or any of the other Windows Address Book (WAB) methods. AllocateBuffer я нигде не делаю Документации действительно не очень Например ADRLIST Structure про память мало чего сказано и дальше если идти по ссылкам ->ADRENTRY->SPropValue Зато вот здесь в аналогичной штуке ADRLIST (Office 2013) до фига чего есть The MAPIAllocateBuffer and MAPIFreeBuffer functions must be used to allocate and free the ADRLIST structure and all its parts. (аналог lpWABObject->AllocateBuffer lpWABObject->FreeBuffer) и дальше Managing Memory for ADRLIST and SRowSet Structures + картинка прилагается Что до MSDN(Windows) явно смущает только IMailUser::GetProps Method lppPropArray SPropValue Address of a pointer to a variable of type SPropValue that receives the property values. The variable must be freed by the client. откуда и родилась строчка lpWABObject->FreeBuffer(lpProps); Изопропилесли с освобождением памяти разобраться не удастся(ввиду кривой документации, в частности) - * следует изолировать в отдельном процессе При завершении приложения память все равно освобождается(думаю да)? Или утекает до перезагрузки компа? Если ДА то проще забить на все FreeBuffer(lpProps), и не уверен что нужны, иначе я действительно все указатели грохаю до того как их надо прочесть в VB. Как я сказал, использование этой кухни нечастое и неактивное (выбрать пару e-mail -структуры небольшие), а окно выбора списка телефонов - отдельный exe, открыл, выбрал закрыл. Про BSTR и копирование строк я идею понял. А если с указателями как у меня, то как их грохать (если мне их надо сначала вернуть)? Или давай так, как мне скопировать указатели в другие (новые) указатели, которые я грохаю уже в VB (моя структура которую я возвращаю). Потому что в VB я грохаю не все props (есть props в ориг. структуре, кот. я не использую, использую 3 из 12 + 4 из 18, остальное стало быть утечка). И тогда уж надо не FreeBuffer(lpProps), а еще FreeBuffer(lpProp[i]) для каждого, и т.д. как разжевано в офисовской документации. Изопропилв коде как минимум двум интерфейсам не делается Release() Где чего писать? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.01.2016, 12:03 |
|
||
|
Как вернуть через API массив структур? API эту сам пишу.
|
|||
|---|---|---|---|
|
#18+
Дмитрий77Изопропилв коде как минимум двум интерфейсам не делается Release() Где чего писать? lpAdrBook->Release( что сюда писать?) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.01.2016, 12:11 |
|
||
|
Как вернуть через API массив структур? API эту сам пишу.
|
|||
|---|---|---|---|
|
#18+
Дмитрий77lpAdrBook->Release( что сюда писать?) А фу, Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. добавил. ; забыл вставить, компилятор ругнулся а там же void ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.01.2016, 12:23 |
|
||
|
Как вернуть через API массив структур? API эту сам пишу.
|
|||
|---|---|---|---|
|
#18+
Изопропилкопируй строки, а не ссылки проще создавать/освобождать SysAllocString/SysFreeString (BSTR внутри будут) Здесь ты думаю прав. С Код: 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. 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. .Net Код: vbnet 1. Т.е. что сделал: 1) заменил в структуре строки на BSTR, добавил SysAllocString(m_строка) 2) применил lpWABObject->FreeBuffer() ко всему к чему применилось и не противоречит здравому смыслу (начитавшись оффисовской документации по структуре ADRLIST) Код: plaintext 1. 2. 3. 4. 5. при этом компилятор не дал мне сделать Код: plaintext 1. 2. хз 3) Вернул опять CoTaskMemAlloc/ Marshal.FreeCoTaskMem(PtrRecipList) 4) ->Release для интерфейсов в 3 места добавил как было сказано Вроде все прилично вышло, без иероглифов, вылетов и висяков. Изопропилосвобождение памяти, как я уже и говорил, лучше сделать отдельным вызовом типа CPP_AddressBookFree(PtrRecipList,num) - и строки почистить и массив структур - всё в c++ коде, который точно знает что и как размещалось) здесь хуже Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. Код: vbnet 1. 2. 3. 4. 1) если CPP_AddressBookFree в СИ сделать пустую (в теле ф-ции оставить только ;), то съедает (естественно ничего не делая) 2) на блок с SysFreeString .Net дает ошибку Необработанное исключение типа "System.AccessViolationException" в WabTestNet.exe Дополнительные сведения: Попытка чтения или записи в защищенную память. Это часто свидетельствует о том, что другая память повреждена. 3) Если блок с SysFreeString .Net закомментировать (оставить только CoTaskMemFree(* lppRecipList);), то .Net не ругается но тупо виснет с колесиком типа "песочные часики". Чет напортачил опять, пока идей нет. CoTaskMemFree конечно можно сделать и из VB (Marshal.FreeCoTaskMem) как и делал, а насчет SysFreeString чет не уверен. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.01.2016, 03:08 |
|
||
|
Как вернуть через API массив структур? API эту сам пишу.
|
|||
|---|---|---|---|
|
#18+
Дмитрий77а насчет SysFreeString чет не уверен. Marshal.FreeBSTR но лучше баги вычистить ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.01.2016, 10:23 |
|
||
|
Как вернуть через API массив структур? API эту сам пишу.
|
|||
|---|---|---|---|
|
#18+
ИзопропилMarshal.FreeBSTR через .Net у меня что-то с ходу не получилось. Изопропилно лучше баги вычистить Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. Правдоподобно? Вроде не глючит, закомментированными строками проверял что там действительно то что я кидал в .Net. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.01.2016, 04:33 |
|
||
|
Как вернуть через API массив структур? API эту сам пишу.
|
|||
|---|---|---|---|
|
#18+
Ну с выбором контактов вроде разобрался. Но я еще задачу хочу решить. Допустим есть выбранный список, ну т.е. [DispayName<]myemail@myserver.com[>] (или напр. 3 списка To CC BCC) Я хочу подать эту входную инфо в IAdrBook::Address , чтобы отобразить уже выбранные адреса в диалоге Выбор Адресата, удалить дополнить и т.п. Для этого мне надо подать LPADRLIST lppAdrList ( ADRLIST Structure ) на вход вместо NULL. Далее адресаты бывают Resolved (полноценная структура ADRENTRY Structure ) -соответствуют записи в контактах - отображается нормальным образом (в To,CC, или BCC) и Unresolved (неполноценная структура) -не выяснено или отсутствует в контактах адресной книги отображается красным знаком вопроса (в To,CC, или BCC) Чтобы сделать Unresolved-> Resolved надо так понял применить IAddrBook::ResolveName Method к грубо набросанной структуре LPADRLIST lppAdrList (напр. указывается только одно св-во: email адрес, ResolveName вытаскивает имя и т.п.) Попробовал такой тест: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. Если выделенная строчка ResolveName закомментирована или дает "error", то передаваемый lppAdrList не модифицируется (т.е. адресат добавляется но со знаком красного вопроса -Unresolved). А вот если OK, то возвращается структура в которой все строки пустые (кроме PR_RECIPIENT_TYPE который ULONG). Соответственно адресат вообще не отображается. Что тут не так в моем коде? (насчет AllocateBuffer/FreeBuffer пока не делал, просьба не предираться, AllocateBuffer-ы вроде сделал правильно ). Пока пробую в чисто C exe. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2016, 05:54 |
|
||
|
Как вернуть через API массив структур? API эту сам пишу.
|
|||
|---|---|---|---|
|
#18+
Я вот чего не понимаю, попробовал в ANSI -все работает: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. Вася добавляется в список адресатов, причем даже без знака вопроса (c возможностью сразу добавить в адр. книгу через свойства). Аналогичный код в Юникоде: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. не работает как писал в посте выше, хотя вроде все корректно заменил:_W, .lpszW, MAPI_UNICODE флаг задал Мне нужен Юникод. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2016, 13:12 |
|
||
|
Как вернуть через API массив структур? API эту сам пишу.
|
|||
|---|---|---|---|
|
#18+
Все, заработало: UNICODE Support in WAB ResolveNameSpecify WAB_RESOLVE_UNICODE (not MAPI_UNICODE) if all strings in the ADRLIST are in UNICODE. The returned strings are in UNICODE. Otherwise, all in and out strings are ANSI/DBCS. Почему-то смотрел в описание совсем другой ф-ции: IABContainer::ResolveNames Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2016, 13:36 |
|
||
|
|

start [/forum/topic.php?all=1&fid=57&tid=2018644]: |
0ms |
get settings: |
7ms |
get forum list: |
14ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
170ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
61ms |
get tp. blocked users: |
1ms |
| others: | 280ms |
| total: | 555ms |

| 0 / 0 |
