Проблема с высвобождением памяти в dll
От: anton20vlad  
Дата: 11.03.09 12:07
Оценка:
Нужно написать обёртку для апи предоставлемого одной конторой(потому как типы параметров экспортируемых апишной библиотекой функций имеют только сишный эквивалент). Это понадобилось для того чтобы использовать апи в Делфи.

Вот то что у меня в обёртке на экспорт:
DIVA_STATUS DLL_SPEC WDIVA_getRequestInfo(int RequestType, int reqNum)
{


DIVA_REQUEST_INFO requestInfo;

DIVA_STATUS cr = DIVA_getRequestInfo (
reqNum,
&requestInfo
);
return 1;
}

Теперь приведу условные обозначения:
1. #define DLL_SPEC __declspec(dllexport)
2. DIVA_STATUS = int
3. class DIVA_REQUEST_INFO { // Introduced in DIVA 5.3

public:

int requestNumber;
DIVA_REQUEST_TYPE requestType;
DIVA_REQUEST_STATE requestState;
int progress; // from 0 to 100 (%)
// may always be 0 if not significant or not available
DIVA_ABORTION_REASON abortionReason;
DIVA_OBJECT_SUMMARY objectSummary;
DIVA_REPACK_TAPES_INFO repackTapes;
int currentPriority; // From 0 to 100
DIVA_STRING additionalInfo;
// may be 0 is not significant or not available

} ;
4. typedef enum {
DIVA_ARCHIVE_REQUEST = 0,
DIVA_RESTORE_REQUEST,
DIVA_DELЕTЕ_REQUEST,
DIVA_EJECT_REQUEST,
DIVA_INSERT_REQUEST,
DIVA_COPY_REQUEST,
DIVA_RESTORE_INSTANCE_REQUEST,
DIVA_DELЕTЕ_INSTANCE_REQUEST,
DIVA_UNKNOWN_REQUEST_TYPE,
DIVA_AUTOMATIC_REPACK_REQUEST,
DIVA_ONDEMAND_REPACK_REQUEST,
DIVA_ASSOC_COPY_REQUEST,
DIVA_PARTIAL_RESTORE_REQUEST,
DIVA_MULTIPLE_RESTORE_REQUEST,
DIVA_TRANSCODE_ARCHIVED_REQUEST
} DIVA_REQUEST_TYPE ;

5.typedef enum {

DIVA_PENDING = 0,
DIVA_TRANSFERRING,
DIVA_MIGRATING,
DIVA_COMPLETED,
DIVA_ABORTED,
DIVA_CANCELLED,
DIVA_UNKNOWN_STATE,
DIVA_DELETING,
DIVA_WAITING_FOR_RESOURCES,
DIVA_WAITING_FOR_OPERATOR,
DIVA_ASSIGNING_POOL,
DIVA_PARTIALLY_ABORTED,
DIVA_RUNNING

} DIVA_REQUEST_STATE;

6. class DIVA_ABORTION_REASON {

public :

DIVA_ABORTION_CODE code;
DIVA_STRING description;

};

7.typedef enum {

DIVA_AR_NONE = 0,
DIVA_AR_DRIVE,
DIVA_AR_TAPE,
DIVA_AR_ACTOR,
DIVA_AR_DISK,
DIVA_AR_DISK_FULL,
DIVA_AR_SOURCE_DEST,
DIVA_AR_RESOURCES,
DIVA_AR_LIBRARY,
DIVA_AR_PARAMETERS,
DIVA_AR_UNKNOWN,
DIVA_AR_INTERNAL,
DIVA_AR_SOURCE_DEST2 //Error using Destination 2 (BACKUP) during Y-Restore

} DIVA_ABORTION_CODE;

8.typedef std::wstring DIVA_STRING;
9.class DIVA_OBJECT_SUMMARY {

public :

DIVA_STRING objectName ;
DIVA_STRING objectCategory ;

} ;

10.class DIVA_REPACK_TAPES_INFO {

public :

DIVA_STRING sourceTape ; // the tape being repacked
DIVA_STRING destinationTape ; // the new tape created from sourceTape

} ;



Вроде всё. Вобщем проблема возникает после использования функции WDIVA_getRequestInfo в основной программе на Делфи. Я так понимаю ошибка возникает при попытке высвободить память занятую под DIVA_REQUEST_INFO. Подскажите как это лечится?



После раздумий и общения на форумах надумал написать что-то вроде:
DIVA_STATUS DLL_SPEC WDIVA_getRequestInfo(int RequestType, int reqNum)
{
                
    
    DIVA_REQUEST_INFO requestInfo;
    
    DIVA_STATUS cr = DIVA_getRequestInfo (
                    reqNum,
                    &requestInfo
                    );

    requestInfo.additionalInfo.~basic_string();
    requestInfo.objectSummary.objectCategory~basic_string();
        requestInfo.objectSummary.objectName.~basic_string();
    requestInfo.repackTapes.destinationTape.~basic_string();
    requestInfo.repackTapes.sourceTape.~basic_string();
    requestInfo.abortionReason.description.~basic_string();
  return 1;
}

Только вот ошибка вылетает при попытки освободить память с помощью деструктора ~basic_string(); Что я делаю не так?

добавил раскраску, а форматировать авторский текст — махнул рукой. — Кодт
Re: Проблема с высвобождением памяти в dll
От: A.Lokotkov Россия  
Дата: 11.03.09 12:17
Оценка: +1
Здравствуйте, anton20vlad, Вы писали:

A>Нужно написать обёртку для апи предоставлемого одной конторой(потому как типы параметров экспортируемых апишной библиотекой функций имеют только сишный эквивалент). Это понадобилось для того чтобы использовать апи в Делфи.


stl-строка, похоже, аллокируется и освобождается разными new и delete. Вообще не очень здорово выставлять что-нибудь stl-ное через границу dll, если только явно не передавать туда-сюда общий аллокатор.
bloß it hudla
Re[2]: Проблема с высвобождением памяти в dll
От: anton20vlad  
Дата: 11.03.09 12:26
Оценка:
Здравствуйте, A.Lokotkov, Вы писали:

AL>stl-строка, похоже, аллокируется и освобождается разными new и delete. Вообще не очень здорово выставлять что-нибудь stl-ное через границу dll, если только явно не передавать туда-сюда общий аллокатор.


Спасибо, за ответ. У меня нет вариантов — так сваяли библиотеку апишную буржуи. Я честно говоря уже все мозги сломал как решить эту проблему? Да я понимаю что оно в разных местах выделяется и высвобождается, но в этом конкретном случае что нужно сделать чтобы избавится от ошибки?
Re[3]: Проблема с высвобождением памяти в dll
От: A.Lokotkov Россия  
Дата: 11.03.09 12:44
Оценка:
Здравствуйте, anton20vlad, Вы писали:

A> Я честно говоря уже все мозги сломал как решить эту проблему? Да я понимаю что оно в разных местах выделяется и высвобождается, но в этом конкретном случае что нужно сделать чтобы избавится от ошибки?


Я правильно понимаю, что их API тоже выставлено из их DLL и нет доступа к исходникам?
P.S. Кстати, явный вызов деструкторов однозначно идет в сад.
bloß it hudla
Re[4]: Проблема с высвобождением памяти в dll
От: anton20vlad  
Дата: 11.03.09 12:46
Оценка:
Здравствуйте, A.Lokotkov, Вы писали:

AL>Здравствуйте, anton20vlad, Вы писали:


A>> Я честно говоря уже все мозги сломал как решить эту проблему? Да я понимаю что оно в разных местах выделяется и высвобождается, но в этом конкретном случае что нужно сделать чтобы избавится от ошибки?


AL>Я правильно понимаю, что их API тоже выставлено из их DLL и нет доступа к исходникам?

AL>P.S. Кстати, явный вызов деструкторов однозначно идет в сад.

Правильно. Исходников нет и не будет (. Явный вызов деструкторов от отчаяния...Уж не знаю, можно ли вобще решить эту проблему.
Re[5]: Проблема с высвобождением памяти в dll
От: A.Lokotkov Россия  
Дата: 11.03.09 12:58
Оценка:
Здравствуйте, anton20vlad, Вы писали:

Отвратительный Костыль:

DIVA_STATUS DLL_SPEC WDIVA_getRequestInfo(int RequestType, int reqNum)
{
  DIVA_REQUEST_INFO requestInfo;
  requestInfo.additionalInfo.reserve(512);
  requestInfo.objectSummary.objectCategory.reserve(512);
  requestInfo.objectSummary.objectName.reserve(512);
  requestInfo.repackTapes.destinationTape.reserve(512);
  requestInfo.repackTapes.sourceTape.reserve(512);
  requestInfo.abortionReason.description.reserve(512);
  // если хватит этих размеров и если там внутри кому-нибудь не подменят буфер
  DIVA_STATUS cr = DIVA_getRequestInfo ( reqNum, &requestInfo );
  // и т.д.
  return 1;
}
bloß it hudla
Re[5]: Проблема с высвобождением памяти в dll
От: Danchik Украина  
Дата: 11.03.09 13:03
Оценка:
Здравствуйте, anton20vlad, Вы писали:

A>Здравствуйте, A.Lokotkov, Вы писали:


AL>>Здравствуйте, anton20vlad, Вы писали:


A>>> Я честно говоря уже все мозги сломал как решить эту проблему? Да я понимаю что оно в разных местах выделяется и высвобождается, но в этом конкретном случае что нужно сделать чтобы избавится от ошибки?


AL>>Я правильно понимаю, что их API тоже выставлено из их DLL и нет доступа к исходникам?

AL>>P.S. Кстати, явный вызов деструкторов однозначно идет в сад.

A>Правильно. Исходников нет и не будет (. Явный вызов деструкторов от отчаяния...Уж не знаю, можно ли вобще решить эту проблему.


Запости куда то весь хидер ихнего API. По тому что ты написал проблему не решить, какие-то извращенцы вывели в API std::wstring.
Умно... . У тебя не очень много шансов.
Re[6]: Проблема с высвобождением памяти в dll
От: Danchik Украина  
Дата: 11.03.09 13:10
Оценка:
Здравствуйте, A.Lokotkov, Вы писали:

AL>Здравствуйте, anton20vlad, Вы писали:


AL>Отвратительный Костыль:


[Skip]
AL> requestInfo.repackTapes.destinationTape.reserve(512);

Согласен, вариант решения, но тут куча факторов — Debug/Release, версия студии, версия STL. Придется ему попотеть пока все сложится
Может как то аллокатор перенаправить, на кучу из DLL?
Re[6]: Проблема с высвобождением памяти в dll
От: anton20vlad  
Дата: 11.03.09 13:15
Оценка:
Здравствуйте, A.Lokotkov, Вы писали:

AL>Здравствуйте, anton20vlad, Вы писали:


AL>Отвратительный Костыль:


AL>
AL>DIVA_STATUS DLL_SPEC WDIVA_getRequestInfo(int RequestType, int reqNum)
AL>{
AL>  DIVA_REQUEST_INFO requestInfo;
AL>  requestInfo.additionalInfo.reserve(512);
AL>  requestInfo.objectSummary.objectCategory.reserve(512);
AL>  requestInfo.objectSummary.objectName.reserve(512);
AL>  requestInfo.repackTapes.destinationTape.reserve(512);
AL>  requestInfo.repackTapes.sourceTape.reserve(512);
AL>  requestInfo.abortionReason.description.reserve(512);
AL>  // если хватит этих размеров и если там внутри кому-нибудь не подменят буфер
AL>  DIVA_STATUS cr = DIVA_getRequestInfo ( reqNum, &requestInfo );
AL>  // и т.д.
AL>  return 1;
AL>}
AL>


Спасибо за вариант.

AL>если хватит этих размеров и если там внутри кому-нибудь не подменят буфер


Похоже что подменяют... Всё та же ошибка. Сейчас постараюсь выложить хедер.
Re[7]: Проблема с высвобождением памяти в dll
От: anton20vlad  
Дата: 11.03.09 13:23
Оценка:
Здравствуйте, Danchik, Вы писали:

D>Здравствуйте, A.Lokotkov, Вы писали:


AL>>Здравствуйте, anton20vlad, Вы писали:


AL>>Отвратительный Костыль:


D>[Skip]

AL>> requestInfo.repackTapes.destinationTape.reserve(512);

D>Согласен, вариант решения, но тут куча факторов — Debug/Release, версия студии, версия STL. Придется ему попотеть пока все сложится

D>Может как то аллокатор перенаправить, на кучу из DLL?

http://tab.net.ua/sites/files/site_name.anton20vlad/id.101082/ — хедер.

Debug, Visual C++ v6.0. Библиотеку обёртку использую в делфёвой прикладухе. Версии STL не знаю.
Re[8]: Проблема с высвобождением памяти в dll
От: Danchik Украина  
Дата: 11.03.09 13:51
Оценка:
Здравствуйте, anton20vlad, Вы писали:

A>Здравствуйте, Danchik, Вы писали:


D>>Здравствуйте, A.Lokotkov, Вы писали:


AL>>>Здравствуйте, anton20vlad, Вы писали:


AL>>>Отвратительный Костыль:


D>>[Skip]

AL>>> requestInfo.repackTapes.destinationTape.reserve(512);

D>>Согласен, вариант решения, но тут куча факторов — Debug/Release, версия студии, версия STL. Придется ему попотеть пока все сложится

D>>Может как то аллокатор перенаправить, на кучу из DLL?

A>http://tab.net.ua/sites/files/site_name.anton20vlad/id.101082/ — хедер.


A>Debug, Visual C++ v6.0. Библиотеку обёртку использую в делфёвой прикладухе. Версии STL не знаю.


diva.lib есть? Я так смотрю тут методы класов экспортируются.
Тут нужно будет слинковаться с этой либой. Хотя честно не понимаю как они думали использовать STL в API, экспорта на эти класы нет.
Вы вообще можете ее коректно использовать просто в CPP проэкте?
Какие у вас возможности линковаться с этой библиотекой? Возможна ли статическая линковка (no DLL)
Re[7]: Проблема с высвобождением памяти в dll
От: A.Lokotkov Россия  
Дата: 11.03.09 13:55
Оценка:
Здравствуйте, anton20vlad, Вы писали:

A>Похоже что подменяют... Всё та же ошибка. Сейчас постараюсь выложить хедер.


Учитывая степень запущенности случая, они могут там у себя запросто использовать копирующее присваивание, сгенеренное компилятором, всему интерфейсному объекту, в результате чего ни один костыль не поможет в принципе.
bloß it hudla
Re[9]: Проблема с высвобождением памяти в dll
От: anton20vlad  
Дата: 11.03.09 14:01
Оценка:
D>diva.lib есть? Я так смотрю тут методы класов экспортируются.
D>Тут нужно будет слинковаться с этой либой. Хотя честно не понимаю как они думали использовать STL в API, экспорта на эти класы нет.
D>Вы вообще можете ее коректно использовать просто в CPP проэкте?
D>Какие у вас возможности линковаться с этой библиотекой? Возможна ли статическая линковка (no DLL)

Вот либ http://tab.net.ua/sites/files/site_name.anton20vlad/id.101087/

Мне нужно использовать это Апи в Делфи приложении. Вариант с++ отпадает. Экспортируемые параметры функций в атой АПИшной библиотеке мягко говоря не стандартны, поэтому из Делфей я эти функции использовать просто не могу. Поэтому пишу обёртку для вот например getRequestInfo. К обёрточной библиотеке прикручиваю АПИшную так:

#pragma comment(lib, "DIVAapi.lib")

Проблема стала только с getRequestInfo. С отстальными (partialRestore например) подобных трудностей не возникло. Всё работает без проблем. Как по Вашему, есть ли ещё какие-то возможности справится с возникшей трудностью?
Re[7]: Проблема с высвобождением памяти в dll
От: A.Lokotkov Россия  
Дата: 11.03.09 14:12
Оценка:
Здравствуйте, Danchik, Вы писали:

D>Может как то аллокатор перенаправить, на кучу из DLL?


Аллокатор надо передавать каждой stl-строке при конструировании интерфейсного объекта в клиентском коде перед тем вызовом. Тогда, если авторы не используют копирующее присваивание для интерфейсного объекта, костыль может помочь.
bloß it hudla
Re[10]: Проблема с высвобождением памяти в dll
От: Danchik Украина  
Дата: 11.03.09 14:24
Оценка:
Здравствуйте, anton20vlad, Вы писали:



D>>diva.lib есть? Я так смотрю тут методы класов экспортируются.

D>>Тут нужно будет слинковаться с этой либой. Хотя честно не понимаю как они думали использовать STL в API, экспорта на эти класы нет.
D>>Вы вообще можете ее коректно использовать просто в CPP проэкте?
D>>Какие у вас возможности линковаться с этой библиотекой? Возможна ли статическая линковка (no DLL)

A>Вот либ http://tab.net.ua/sites/files/site_name.anton20vlad/id.101087/


A>Мне нужно использовать это Апи в Делфи приложении. Вариант с++ отпадает. Экспортируемые параметры функций в атой АПИшной библиотеке мягко говоря не стандартны, поэтому из Делфей я эти функции использовать просто не могу. Поэтому пишу обёртку для вот например getRequestInfo. К обёрточной библиотеке прикручиваю АПИшную так:


A>#pragma comment(lib, "DIVAapi.lib")


Еще раз повторюсь, вы можете корректно использовать эту бибилотеку в CPP проэкте?
Или вам сразу прислали эти хидеры, lib и сказали писать Wrapper для Delphi?
Если у вас есть проэкт на CPP, который линкуется с ней замечательно, то я б на вашем месте сделал копию этого проэкта, и повыкидывал оттуда лишнее или аккуратно скопировал из него все настройки компиляции и линковки в вашу новую DLL.
Потом можна придумать какой интерфейс вывести для Delphi.

A>Проблема стала только с getRequestInfo. С отстальными (partialRestore например) подобных трудностей не возникло. Всё работает без проблем. Как по Вашему, есть ли ещё какие-то возможности справится с возникшей трудностью?


Тут всюду Undefined Behaviour и я бы с такой уверенностью что все гуд не говорил. Вылетит позже.
Re[8]: Проблема с высвобождением памяти в dll
От: A.Lokotkov Россия  
Дата: 11.03.09 14:26
Оценка:
AL>Здравствуйте, Danchik, Вы писали:

D>>Может как то аллокатор перенаправить, на кучу из DLL?


В предыдущем посте я погорячился. На самом деле проблем бы не было вообще, если бы для того интерфейсного объекта в DLL авторы бы сделали явные конструктор и деструктор и экспортировали их из DLL. Тогда всегда вызывались бы они, и правильно освобождали память.

Последний вариант: завести интерфейсный объект статически в клиентском коде и реюзать взякий раз, когда нужно обратиться к той функции.
bloß it hudla
Re[3]: Проблема с высвобождением памяти в dll
От: MasterZiv СССР  
Дата: 11.03.09 16:54
Оценка:
anton20vlad пишет:

> Спасибо, за ответ. У меня нет вариантов — так сваяли библиотеку апишную

> буржуи. Я честно говоря уже все мозги сломал как решить эту проблему?

А никак ты её не решишь. Тебе надо использовать то же CRT, что и у этой
библиотеки. Видимо, это в данном случае MSVCRT, поскольку кроме неё и
дельфы уже там ничего не осталось. А это, видимо, невозможно в билдере.

Да
> я понимаю что оно в разных местах выделяется и высвобождается, но в этом
> конкретном случае что нужно сделать чтобы избавится от ошибки?

-- не удалять
-- (больше идей нет) ...
Posted via RSDN NNTP Server 2.1 beta
Re[5]: Проблема с высвобождением памяти в dll
От: MasterZiv СССР  
Дата: 11.03.09 16:55
Оценка:
anton20vlad пишет:

> AL>Я правильно понимаю, что их API тоже выставлено из их DLL и нет

> доступа к исходникам?
> AL>P.S. Кстати, явный вызов деструкторов однозначно идет в сад.
>
> Правильно. Исходников нет и не будет (. Явный вызов деструкторов от
> отчаяния...

Явный вызов деструктора ничем не плох, но он вам не освободит
память и он может быть вообще недоступен из другого модуля (.dll), это же STL,
темплейты....
Posted via RSDN NNTP Server 2.1 beta
Re[6]: Проблема с высвобождением памяти в dll
От: anton20vlad  
Дата: 11.03.09 17:01
Оценка:
Проблема решилась VirtualAlloc, VirtualFree. Всё красиво и тихо отрабатывает. Только вот не уверен что это правильное решение )
Re[7]: Проблема с высвобождением памяти в dll
От: A.Lokotkov Россия  
Дата: 11.03.09 17:08
Оценка:
Здравствуйте, anton20vlad, Вы писали:

A>Проблема решилась VirtualAlloc, VirtualFree. Всё красиво и тихо отрабатывает. Только вот не уверен что это правильное решение )


Как именно оно решилось?
bloß it hudla
Re[8]: Проблема с высвобождением памяти в dll
От: anton20vlad  
Дата: 11.03.09 17:13
Оценка:
Здравствуйте, A.Lokotkov, Вы писали:

AL>Здравствуйте, anton20vlad, Вы писали:


A>>Проблема решилась VirtualAlloc, VirtualFree. Всё красиво и тихо отрабатывает. Только вот не уверен что это правильное решение )


AL>Как именно оно решилось?


DIVA_STATUS DLL_SPEC WDIVA_getRequestInfo(RequestInfo *reqInf, int reqNum)
{
                
   DIVA_REQUEST_INFO* requestInfo = (DIVA_REQUEST_INFO *)VirtualAlloc(NULL,sizeof(DIVA_REQUEST_INFO),MEM_COMMIT,PAGE_READWRITE);
   DIVA_STATUS cr = DIVA_getRequestInfo (
                    reqNum,
                    requestInfo
                    );
    
    if (cr == DIVA_OK) 
    {
      reqInf->progress = requestInfo->progress;
      reqInf->requestType = requestInfo->requestType;
      reqInf->requestState = requestInfo->requestState;
      reqInf->abortionCode = DIVA_AR_NONE;

      if (requestInfo->requestState == DIVA_ABORTED || requestInfo->requestState == DIVA_PARTIALLY_ABORTED) 
      {
          reqInf->abortionCode = requestInfo->abortionReason.code; 
                        
      }
                    
    }
   VirtualFree(requestInfo,0,MEM_RELEASE);

   return cr;             

}


Никаких ошибок с памятью, отрабатывает как надо.
Re[9]: Проблема с высвобождением памяти в dll
От: A.Lokotkov Россия  
Дата: 11.03.09 17:25
Оценка:
Здравствуйте, anton20vlad, Вы писали:

A>Никаких ошибок с памятью, отрабатывает как надо.


Вы можете рассказать, почему Вы сделали именно так и почему оно перестало падать?
bloß it hudla
Re[10]: Проблема с высвобождением памяти в dll
От: anton20vlad  
Дата: 11.03.09 17:28
Оценка:
Здравствуйте, A.Lokotkov, Вы писали:

AL>Здравствуйте, anton20vlad, Вы писали:


A>>Никаких ошибок с памятью, отрабатывает как надо.


AL>Вы можете рассказать, почему Вы сделали именно так и почему оно перестало падать?



Перебирал варианты ) и сделал так. А вот насчёт почему перестало падать...думаю что решился вопрос с тем где именно и кем выделяется и высвобождается память. Вы видите какую-то ошибку в коде?
Re[11]: Проблема с высвобождением памяти в dll
От: A.Lokotkov Россия  
Дата: 11.03.09 17:54
Оценка:
Здравствуйте, anton20vlad, Вы писали:

A>Перебирал варианты ) и сделал так. А вот насчёт почему перестало падать...думаю что решился вопрос с тем где именно и кем выделяется и высвобождается память. Вы видите какую-то ошибку в коде?


Конструктор и деструктор интерфейсного объекта на клиентской стороне теперь не вызываются. Поскольку не вызывается конструктор, для каждой stl-строки внутри интерфейсного объекта DIVA_REQUEST_INFO не создается небольшой умолчательный буфер, -- там будет NULL. Когда несконструированный интерфейсный объект с несконструированными строками внутри передается в их dll, stl почему-то не падает. Может быть, потому что, увидев NULL, аллокирует буфера в строках на стороне dll. Если это так, то после того, как Вы делаете VirtualFree на своей стороне, память, выделенная под буфера строк, никогда не будет освобождена (по-крайней мере, до выгрузки выделившей ее dll). Для такого решения необязательно делать именно VirualAlloc/VirualFree, я думаю, с тем же успехом можно было бы написать как-нибудь так:

DIVA_STATUS DLL_SPEC WDIVA_getRequestInfo(RequestInfo *reqInf, int reqNum)
{
  __int64 placement[sizeof(DIVA_REQUEST_INFO) + sizeof(__int64) - 1];
  memset(placement, 0, (sizeof(DIVA_REQUEST_INFO) + sizeof(__int64) - 1));
  DIVA_REQUEST_INFO* requestInfo = reinterpret_cast<DIVA_REQUEST_INFO*>(placement);
  DIVA_STATUS cr = DIVA_getRequestInfo (reqNum, requestInfo);
  //...
  return cr;             
}
bloß it hudla
Re: Проблема с высвобождением памяти в dll
От: g_i  
Дата: 11.03.09 18:45
Оценка:
Здравствуйте, anton20vlad, Вы писали:

Динамический рантайм мог бы спасти отца русской демократии
Re[2]: Проблема с высвобождением памяти в dll
От: MasterZiv СССР  
Дата: 11.03.09 22:05
Оценка: -1
g_i пишет:

> Динамический рантайм мог бы спасти отца русской демократии


у него он и так динамический. Другого не бывает в .dll.
Posted via RSDN NNTP Server 2.1 beta
Re[3]: Проблема с высвобождением памяти в dll
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 12.03.09 04:10
Оценка:
Здравствуйте, MasterZiv, Вы писали:

>> Динамический рантайм мог бы спасти отца русской демократии

MZ>у него он и так динамический. Другого не бывает в .dll.

/MT для при сборке .dll уже отменили?
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Re[3]: Проблема с высвобождением памяти в dll
От: g_i  
Дата: 12.03.09 05:43
Оценка:
Здравствуйте, MasterZiv, Вы писали:

MZ>g_i пишет:


>> Динамический рантайм мог бы спасти отца русской демократии


MZ>у него он и так динамический. Другого не бывает в .dll.


Судя по описанию проблемы, это не так.
Re[12]: Проблема с высвобождением памяти в dll
От: Аноним  
Дата: 12.03.09 07:34
Оценка:
Здравствуйте, A.Lokotkov, Вы писали:

AL>
AL>DIVA_STATUS DLL_SPEC WDIVA_getRequestInfo(RequestInfo *reqInf, int reqNum)
AL>{
AL>  __int64 placement[sizeof(DIVA_REQUEST_INFO) + sizeof(__int64) - 1];
AL>  memset(placement, 0, (sizeof(DIVA_REQUEST_INFO) + sizeof(__int64) - 1));
AL>  DIVA_REQUEST_INFO* requestInfo = reinterpret_cast<DIVA_REQUEST_INFO*>(placement);
AL>  DIVA_STATUS cr = DIVA_getRequestInfo (reqNum, requestInfo);
AL>  //...
AL>  return cr;             
AL>}
AL>





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

Мне кажется самое простое это 3й вариант. Правда как я понимаю, память всё-равно не высвободится, так как деструктор пустой? И ещё один вопрос: для чего нужно "подмутить методы-аксесоры"? Это я недопонял.
Re[4]: Проблема с высвобождением памяти в dll
От: anton20vlad  
Дата: 12.03.09 07:37
Оценка:
Здравствуйте, Odi$$ey, Вы писали:

OE>Здравствуйте, MasterZiv, Вы писали:


>>> Динамический рантайм мог бы спасти отца русской демократии

MZ>>у него он и так динамический. Другого не бывает в .dll.

OE>/MT для при сборке .dll уже отменили?



/MT при сборке имеется.
Re[4]: Проблема с высвобождением памяти в dll
От: MasterZiv СССР  
Дата: 12.03.09 07:46
Оценка:
g_i пишет:

> MZ>у него он и так динамический. Другого не бывает в .dll.

>
> Судя по описанию проблемы, это не так.

Тем хуже для него. Так может только в этом и проблема ?
А вообще, какой рантайм "Дельфа" использует ?
Posted via RSDN NNTP Server 2.1 beta
Re[12]: Проблема с высвобождением памяти в dll
От: anton20vlad  
Дата: 12.03.09 07:49
Оценка:
Здравствуйте, A.Lokotkov

В продолжение темы с пустым деструктором и про "подмутить методы аксесоры". Судя по всему, их таки надо подмутить так как ошибка никуда не делась...Правда я не понимаю что имеется в виду.
Re[13]: Проблема с высвобождением памяти в dll
От: A.Lokotkov Россия  
Дата: 12.03.09 08:52
Оценка:
Здравствуйте, Аноним, Вы писали:

А>[/list]


А>Мне кажется самое простое это 3й вариант. Правда как я понимаю, память всё-равно не высвободится, так как деструктор пустой? И ещё один вопрос: для чего нужно "подмутить методы-аксесоры"? Это я недопонял.


Я не понял, что коллеги имели в виду. Для того, чтобы все работало правильно, у авторов из DLL должны были быть экспортированы конструктор и деструктор интерфейсного объекта DIVA_REQUEST_INFO. Тогда проблем бы не было вообще (ну, вернее, были бы, но они решались бы путем добровольного запрета на доступ к строковым членам из клиента по записи), поскольку при любом способе создания объекта DIVA_REQUEST_INFO на клиентской стороне (по new, на стеке или статически) буферы stl-строк и прочая создавались бы и освобождались в их DLL.
Авторы DLL этого не сделали, поэтому конструктор и деструктор DIVA_REQUEST_INFO, сгенерированные компилятором, всегда вызываются на клиентской стороне и, конструктор, как минимум, создает в каждой stl-строке маленький исходный буфер. А это значит, что у проблемы нет корректного решения, есть только костыли разной степени кривизны типа такого (эскиз, предполагающий, что обертка для delphi также расположена в dll):

// Используется для всех запросов к той DLL
// При необходимости использования из разных потоков
// дооснастить крит.секцией.
static DIVA_REQUEST_INFO* globalRequestor = NULL;

BOOL APIENTRY DllMain( HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved )
{
    switch (ul_reason_for_call)
    {
      case DLL_PROCESS_ATTACH:
      {
        globalRequestor = (DIVA_REQUEST_INFO*) new [sizeof(DIVA_REQUEST_INFO) + sizeof(__int64) - 1];
        // В этом случае все аллокации stl-строк будут всегда выполняться на стороне их DLL,
        // и память не потечет.
        if(globalRequestor != NULL)
          memset(globalRequestor, 0, (sizeof(DIVA_REQUEST_INFO) + sizeof(__int64) - 1));
      }
      break;
      case DLL_PROCESS_DETACH:
      {
        // в принципе, не очень-то и нужно
        if(globalRequestor != NULL)
          delete [] globalRequestor;
      }
          break;
    }
    return TRUE;
}

DIVA_STATUS DLL_SPEC WDIVA_getRequestInfo(RequestInfo *reqInf, int reqNum)
{
  // передаем глобальный интерфейсный объект
  DIVA_STATUS cr = DIVA_getRequestInfo (reqNum, globalRequestor);
  //...
  return cr;             
}


У меня больше нет идей.
bloß it hudla
Re[5]: Проблема с высвобождением памяти в dll
От: Danchik Украина  
Дата: 12.03.09 11:25
Оценка:
Здравствуйте, MasterZiv, Вы писали:

MZ>g_i пишет:


>> MZ>у него он и так динамический. Другого не бывает в .dll.

>>
>> Судя по описанию проблемы, это не так.

MZ>Тем хуже для него. Так может только в этом и проблема ?

MZ>А вообще, какой рантайм "Дельфа" использует ?

Тут до Delphi еще далеко, он CPP не может заставить работать.
Re[5]: Проблема с высвобождением памяти в dll
От: g_i  
Дата: 12.03.09 12:04
Оценка:
Здравствуйте, anton20vlad, Вы писали:

A>Здравствуйте, Odi$$ey, Вы писали:


OE>>Здравствуйте, MasterZiv, Вы писали:


>>>> Динамический рантайм мог бы спасти отца русской демократии

MZ>>>у него он и так динамический. Другого не бывает в .dll.

OE>>/MT для при сборке .dll уже отменили?



A>/MT при сборке имеется.


У вас имеется dll. С каким рантаймом собрана эта dll? Со статическим? Заказать пересборку с динамическим можно?
Важно чтобы оба модуля (клиент и длл) использовали один тип рантайма. Затем важно чтобы они могли работать с одной и той-же версией рантайм dll.
Re[6]: Проблема с высвобождением памяти в dll
От: g_i  
Дата: 12.03.09 12:08
Оценка:
Здравствуйте, g_i, Вы писали:

Сам себя запутал.
DLL собираешь ты. Используй динамический рантайм если клиент сможет использовать динамический рантайм.
Если нет — не используй string. Вообще, откуда проблема с деструктором std::string если ты утверждаешь, что допустимы только сишные экспорты?
Re[3]: Проблема с высвобождением памяти в dll
От: alsemm Россия  
Дата: 12.03.09 12:41
Оценка:
Здравствуйте, anton20vlad, Вы писали:

A>Спасибо, за ответ. У меня нет вариантов — так сваяли библиотеку апишную буржуи. Я честно говоря уже все мозги сломал как решить эту проблему? Да я понимаю что оно в разных местах выделяется и высвобождается, но в этом конкретном случае что нужно сделать чтобы избавится от ошибки?

Я правильно понимаю, что, проблема состоит только в том, что приложение валится, когда дело доходит до разрушения локальной DIVA_REQUEST_INFO requestInfo; внутри WDIVA_getRequestInfo()?
Ваша обертка и буржуйский код используют совместимые версии STL, т.е. строки в структуре requestInfo инициализирются корректно?
Если все так, то можно так попробовать проблему решить:
DIVA_STATUS DLL_SPEC WDIVA_getRequestInfo(int RequestType, int reqNum)
{
    static char requestInfoBuffer[sizeof(DIVA_REQUEST_INFO)] = { 0 };

    DIVA_REQUEST_INFO* pRequestInfo = (DIVA_REQUEST_INFO*)&requestInfoBuffer;

    DIVA_STATUS cr = DIVA_getRequestInfo (reqNum, pRequestInfo);
    return 1;
}


Похожее решение тут уже предлагали, только там буфер был локальный, а тут статический. Смысл в статическом буфере в том, что память под строки не будет утекать.

Если у вас приложение многопоточное, то вместо простого глобального статического буфера можно использовать буфер из TLS.

Алексей
Re[6]: Проблема с высвобождением памяти в dll
От: MasterZiv СССР  
Дата: 12.03.09 16:37
Оценка: -2
g_i пишет:

> У вас имеется dll. С каким рантаймом собрана эта dll? Со статическим?

> Заказать пересборку с динамическим можно?

Если какая-то DLL собрана со статическим рантаймом, то её, за исключением очень
редких случаев очень грамотного проектирования интерфейсов этой .DLL,
которые в жизни почти не встречаются, и к числу которых данная .DLL явно НЕ
относится, МОЖНО СРАЗУ ЖЕ ВЫКИНУТЬ НА ПОМОЙКУ, как непригодную к использованию.
Posted via RSDN NNTP Server 2.1 beta
Re[6]: Проблема с высвобождением памяти в dll
От: MasterZiv СССР  
Дата: 12.03.09 16:39
Оценка:
Danchik пишет:

> Тут до Delphi еще далеко, он CPP не может заставить работать.


Да я вообще не очень понимаю, что он там делать собирается,
как он это дело в дельфу вставит ? Легче наверное новый язык
программирования изучить, чем это вот сделать.
Posted via RSDN NNTP Server 2.1 beta
Re[7]: Проблема с высвобождением памяти в dll
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 13.03.09 04:09
Оценка:
Здравствуйте, MasterZiv, Вы писали:

MZ>Если какая-то DLL собрана со статическим рантаймом, то её, за исключением очень

MZ>редких случаев очень грамотного проектирования интерфейсов этой .DLL,
MZ>которые в жизни почти не встречаются, и к числу которых данная .DLL явно НЕ
MZ>относится, МОЖНО СРАЗУ ЖЕ ВЫКИНУТЬ НА ПОМОЙКУ, как непригодную к использованию.

обосновать можешь?
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Re[7]: Проблема с высвобождением памяти в dll
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 13.03.09 04:13
Оценка:
Здравствуйте, MasterZiv, Вы писали:

MZ>Если какая-то DLL собрана со статическим рантаймом,


и кстати уж определись внутри себя, толи ... динамический. Другого не бывает в .dll.
Автор: MasterZiv
Дата: 12.03.09
толи все таки бывает
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Re[8]: Проблема с высвобождением памяти в dll
От: MasterZiv СССР  
Дата: 13.03.09 08:32
Оценка:
Odi$$ey пишет:

> обосновать можешь?


Да, конечно. Если у тебя более одного Win32 модуля в системе,
все эти модули должны иметь один экземпляр CRTL. Иначе (хотя бы)
все нереентерабельные функции типа strtok ТУПО НЕ БУДУТ РАБОТАТЬ,
если они будут вызваны из двух РАЗНЫХ win32 модулей. Потому
что все статические данные CRTL должны быть в одном экземпляре
у приложения (думаю, напоминать, что они есть, не нужно: таблицы
открытых файлов, стандартные потоки ввода-вывода, локали и т.п.).
Это невозможно при сборке со статической CRTL --
их будет как минимум 2 у нескольких Win32-модулей.

Есть конечно и исключения, о которых я говорил — это если
всё использование CRT одним модулем замыкается только внутри одного
модуля. Для этого нужно специальным образом этот модуль проектировать.
Posted via RSDN NNTP Server 2.1 beta
Re[8]: Проблема с высвобождением памяти в dll
От: MasterZiv СССР  
Дата: 13.03.09 08:34
Оценка:
Здравствуйте, Odi$$ey, Вы писали:

OE>и кстати уж определись внутри себя, толи ... динамический. Другого не бывает в .dll.
Автор: MasterZiv
Дата: 12.03.09
толи все таки бывает


Я имел в виду, что в нормальном работающем приложении не бывает. Потому что оно будет неработающим, с учётом всего вышесказанного мной.
Re[9]: Проблема с высвобождением памяти в dll
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 13.03.09 10:39
Оценка:
Здравствуйте, MasterZiv, Вы писали:

>> обосновать можешь?


MZ>Да, конечно. Если у тебя более одного Win32 модуля в системе, все эти модули должны иметь один экземпляр CRTL. Иначе (хотя бы) все нереентерабельные функции типа strtok ТУПО НЕ БУДУТ РАБОТАТЬ, если они будут вызваны из двух РАЗНЫХ win32 модулей.


strtok действительно использует статические переменные при разборе и поэтому нельзя внутри цикла с strtok применять эту функцию к другой строке. Но каким образом эта ситуация еще может ухудшиться из-за разных CRT в разных модулях — я не вижу. Скорее уж наоборот — теперь можно будет сделать внутри цикла strtok одного модуля вызов функции другого модуля внутри которого будет свой strtok — и при этом их статические переменные никак друг на друга не повлияют.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Re[7]: Проблема с высвобождением памяти в dll
От: Danchik Украина  
Дата: 13.03.09 11:42
Оценка: 1 (1)
Здравствуйте, MasterZiv, Вы писали:

MZ>Danchik пишет:


>> Тут до Delphi еще далеко, он CPP не может заставить работать.


MZ>Да я вообще не очень понимаю, что он там делать собирается,

MZ>как он это дело в дельфу вставит ? Легче наверное новый язык
MZ>программирования изучить, чем это вот сделать.

Если изменит интерфейс экспортируемых функций то очень просто. Да хоть COM
Re[10]: Проблема с высвобождением памяти в dll
От: MasterZiv СССР  
Дата: 13.03.09 21:50
Оценка:
Odi$$ey пишет:

> строке. Но каким образом эта ситуация еще может ухудшиться из-за разных

> CRT в разных модулях — я не вижу. Скорее уж наоборот — теперь можно
> будет сделать внутри цикла strtok одного модуля вызов функции другого

У тебя какое-то очень наивное представление о CRTL. Выводы о возможности
улучшения её работы -- тоже. Что же, на каждый поток по CRT будем заводить,
или на каждую функцию ?
Posted via RSDN NNTP Server 2.1 beta
Re[11]: Проблема с высвобождением памяти в dll
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 14.03.09 06:32
Оценка:
Здравствуйте, MasterZiv, Вы писали:

>> строке. Но каким образом эта ситуация еще может ухудшиться из-за разных

>> CRT в разных модулях — я не вижу. Скорее уж наоборот — теперь можно
>> будет сделать внутри цикла strtok одного модуля вызов функции другого

MZ>У тебя какое-то очень наивное представление о CRTL. Выводы о возможности

MZ>улучшения её работы -- тоже. Что же, на каждый поток по CRT будем заводить,
MZ>или на каждую функцию ?

давай не будем обо всем сразу — потоки, наивные представления и проч. bla-bla-bla, можешь показать как у strtok съезжает крыша в dll со статической CRT?
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.