Проблема с высвобождением памяти в 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
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.