Перейти к содержимому

Фото
- - - - -

[C++] Проблемы с памятью при обмене EXE<>DLL


  • Вы не можете создать новую тему
  • Please log in to reply
13 ответов в этой теме

#1 Slash

Slash
  • Пользователь
  • 78 сообщений
  • Откуда:Estonia - Tallinn

Отправлено 24 Февраль 2006 - 11:04

В кратце опишу ситуацию: дана DLL, которая экспортирует функцию, функция получает в качестве параметра указатель на структуру, в которой хранятся указатели на массивы. В клиентской программе создаётся эта структура, заполняется какими-то данными, и передаётся на обработку в DLL. Но вот тут возникает прблема: DLL видит указатель, может считывать данные, но при попытке освободить память она просто ничего не делает, т.е. сообщений об ошибке не выкидывает, вроде всё здорово, но память не освобождается и данные остаются там же где были. Складывается впечатление, что при передаче указателя в DLL, в нём теряется колличество выделенных байт (использованы функции new/delete) или возможно всё дело в правах доступа DLL к heap процесса проги... :( В общем вся эта ситуация меня жутко расстраивает и если кто-нибудь может подсказать в чём причина и возможные выходы из ситуации, буду очень благодарен. Пишу под винду на VC++ 6.0.
  • 0

#2 úlfurinn

úlfurinn

    забавная зверушка

  • Пользователь
  • 178 сообщений

Отправлено 24 Февраль 2006 - 18:26

Если CRT прилинкован статически, по у основного модуля и у дллки будут отдельные экземпляры менеджера памяти. Попробуй прилинковать его к обоим модулям динамически.
  • 0
Насильник и убийца, положительный персонаж.

#3 Slash

Slash
  • Пользователь
  • 78 сообщений
  • Откуда:Estonia - Tallinn

Отправлено 24 Февраль 2006 - 19:07

úlfurinn, а можно технологию поподобнее? Просто DLL'ка прилинкована явно, т.е. прога не знает какую именно DLL она будет загружать...
  • 0

#4 úlfurinn

úlfurinn

    забавная зверушка

  • Пользователь
  • 178 сообщений

Отправлено 24 Февраль 2006 - 22:59

Да лишь бы runtime у них общий был, т.е. в shared-коде.
Если линковать его статически (/MT), то у каждого проекта, у exe и у dll будут свои экземпляры кода менеджера памяти со своим мнением о состоянии кучи, и менеджер памяти, прилинкованный к экзешнику, не будет знать о том, что делает менеджер памяти, прилинкованный к библиотеке. А если сам менеджер памяти будет располагаться в отдельной дллке (/MD), то оба твоих модуля будут использовать один и тот же его экземпляр.

В общем, идея в том, чтобы выделение и освобождение куска памяти происходило в одном и том же месте. Если этого нельзя добиться на уровне своего кода (т.е. чтобы все выделять и освобождать либо только в exe, либо только в dll), остается сделать это на уровне runtime библиотеки.
  • 0
Насильник и убийца, положительный персонаж.

#5 Slash

Slash
  • Пользователь
  • 78 сообщений
  • Откуда:Estonia - Tallinn

Отправлено 03 Март 2006 - 20:44

Т.е. если я всё правильно понял менеджер памяти должен находится в отдельном модуле доступном как экзешке, так и ДЛЛке и общая память должна выделятся только в нём и операции new/delete должны быть там переопределены. Теоретически всё ясно, а не знаешь где взять примеры реализации? Я просто поискал в Google по ключевым словам, но ничего толкового не нашёл, кругом только примеры для Delphi. Может подкинешь линков по теме? :huh:
  • 0

#6 úlfurinn

úlfurinn

    забавная зверушка

  • Пользователь
  • 178 сообщений

Отправлено 06 Март 2006 - 15:06

Какие еще примеры реализации? Все в стандартной библиотеке. Просто прилинкуй ее правильно.
Заморачиваться со своим собственным менеджером памяти -- это я даже так сразу и не придумаю, для каких целей... :)
  • 0
Насильник и убийца, положительный персонаж.

#7 Slash

Slash
  • Пользователь
  • 78 сообщений
  • Откуда:Estonia - Tallinn

Отправлено 03 Апрель 2006 - 17:48

Какие еще примеры реализации? Все в стандартной библиотеке. Просто прилинкуй ее правильно.
Заморачиваться со своим собственным менеджером памяти -- это я даже так сразу и не придумаю, для каких целей... :)

Поэксперементировал с с различными типами линковки, но результат остался прежним, память не удаляется. :( В ексешнике по дефолту стоит /MD (другой поставить не даёт), если в dll стоит /МТ, то ошибки выделения/удаления памяти выражаются сразу в виде фатальных ошибок, если /MD, то ошибки вылетают не сразу, но проведя тесты, я увидел, что память не освобождается, что позже, после переполнения кучи, тоже вызывает ошибки.

ПС Спасибо, что хоть ты мне отвечаешь. :)
  • 0

#8 úlfurinn

úlfurinn

    забавная зверушка

  • Пользователь
  • 178 сообщений

Отправлено 11 Апрель 2006 - 21:09

Тогда не знаю. Разве что переписать код так, чтобы выделение-освобождение в одном месте происходило...
  • 0
Насильник и убийца, положительный персонаж.

#9 sander

sander
  • Пользователь
  • 9 сообщений

Отправлено 01 Июнь 2006 - 12:31

не совсем в курсе тонкостей реализации менеджера на VC++, но можно попробовать использовать виндозный менеджер и юзать GlobalAllocate. при условии конечно, что структура не динамическая
  • 0

#10 AmoresPerros

AmoresPerros
  • Постоялец
  • 657 сообщений

Отправлено 01 Июнь 2006 - 17:49

Slash, ставь soft ice, и вообще прогони все в отладчике и посмотри состояние кучи.
  • 0

#11 sander

sander
  • Пользователь
  • 9 сообщений

Отправлено 06 Июнь 2006 - 11:30

хехе...отладка библиотек - это, можно сказать, искусство :)).. иф ю ноу вот ай мин...
  • 0

#12 Slash

Slash
  • Пользователь
  • 78 сообщений
  • Откуда:Estonia - Tallinn

Отправлено 07 Июль 2006 - 17:50

Тогда не знаю. Разве что переписать код так, чтобы выделение-освобождение в одном месте происходило...

Да я тоже думал о том, чтобы переделать структуру проги как-нибудь так, чтобы память где выделялась, там бы и удалялась... Но видимо я слишком поздно сообразил :( Уже наверное будет проще всё с нуля переписать... Просто когда я начал добавлять функционал ДЛЛ-льный, я и понятия не имел, что такие запары могут случится...

не совсем в курсе тонкостей реализации менеджера на VC++, но можно попробовать использовать виндозный менеджер и юзать GlobalAllocate. при условии конечно, что структура не динамическая

Ну тоже вариант, хотя и грубый... Но если выбора не останется, то придётся наверное заюзать GlobalAllocate, а так не хочется. :)
  • 0

#13 Slash

Slash
  • Пользователь
  • 78 сообщений
  • Откуда:Estonia - Tallinn

Отправлено 03 Октябрь 2006 - 13:58

В общем я решил проблему, если кому интересно, обращайтесь! ;)
  • 0

#14 Lynx

Lynx
  • Пользователь
  • 162 сообщений
  • Откуда:Таллинн

Отправлено 05 Октябрь 2006 - 10:33

А можно всем популярно про то, как же ты все-таки решил проблему?
  • 0