Нужно написать обёртку для апи предоставлемого одной конторой(потому как типы параметров экспортируемых апишной библиотекой функций имеют только сишный эквивалент). Это понадобилось для того чтобы использовать апи в Делфи.
1. #define DLL_SPEC __declspec(dllexport)
2. DIVA_STATUS = int
3. class DIVA_REQUEST_INFO { // Introduced in DIVA 5.3public:
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. Подскажите как это лечится?
После раздумий и общения на форумах надумал написать что-то вроде:
Здравствуйте, anton20vlad, Вы писали:
A>Нужно написать обёртку для апи предоставлемого одной конторой(потому как типы параметров экспортируемых апишной библиотекой функций имеют только сишный эквивалент). Это понадобилось для того чтобы использовать апи в Делфи.
stl-строка, похоже, аллокируется и освобождается разными new и delete. Вообще не очень здорово выставлять что-нибудь stl-ное через границу dll, если только явно не передавать туда-сюда общий аллокатор.
Здравствуйте, A.Lokotkov, Вы писали:
AL>stl-строка, похоже, аллокируется и освобождается разными new и delete. Вообще не очень здорово выставлять что-нибудь stl-ное через границу dll, если только явно не передавать туда-сюда общий аллокатор.
Спасибо, за ответ. У меня нет вариантов — так сваяли библиотеку апишную буржуи. Я честно говоря уже все мозги сломал как решить эту проблему? Да я понимаю что оно в разных местах выделяется и высвобождается, но в этом конкретном случае что нужно сделать чтобы избавится от ошибки?
Здравствуйте, anton20vlad, Вы писали:
A> Я честно говоря уже все мозги сломал как решить эту проблему? Да я понимаю что оно в разных местах выделяется и высвобождается, но в этом конкретном случае что нужно сделать чтобы избавится от ошибки?
Я правильно понимаю, что их API тоже выставлено из их DLL и нет доступа к исходникам?
P.S. Кстати, явный вызов деструкторов однозначно идет в сад.
Здравствуйте, A.Lokotkov, Вы писали:
AL>Здравствуйте, anton20vlad, Вы писали:
A>> Я честно говоря уже все мозги сломал как решить эту проблему? Да я понимаю что оно в разных местах выделяется и высвобождается, но в этом конкретном случае что нужно сделать чтобы избавится от ошибки?
AL>Я правильно понимаю, что их API тоже выставлено из их DLL и нет доступа к исходникам? AL>P.S. Кстати, явный вызов деструкторов однозначно идет в сад.
Правильно. Исходников нет и не будет (. Явный вызов деструкторов от отчаяния...Уж не знаю, можно ли вобще решить эту проблему.
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;
}
Здравствуйте, anton20vlad, Вы писали:
A>Здравствуйте, A.Lokotkov, Вы писали:
AL>>Здравствуйте, anton20vlad, Вы писали:
A>>> Я честно говоря уже все мозги сломал как решить эту проблему? Да я понимаю что оно в разных местах выделяется и высвобождается, но в этом конкретном случае что нужно сделать чтобы избавится от ошибки?
AL>>Я правильно понимаю, что их API тоже выставлено из их DLL и нет доступа к исходникам? AL>>P.S. Кстати, явный вызов деструкторов однозначно идет в сад.
A>Правильно. Исходников нет и не будет (. Явный вызов деструкторов от отчаяния...Уж не знаю, можно ли вобще решить эту проблему.
Запости куда то весь хидер ихнего API. По тому что ты написал проблему не решить, какие-то извращенцы вывели в API std::wstring.
Умно... . У тебя не очень много шансов.
Согласен, вариант решения, но тут куча факторов — Debug/Release, версия студии, версия STL. Придется ему попотеть пока все сложится
Может как то аллокатор перенаправить, на кучу из DLL?
Здравствуйте, Danchik, Вы писали:
D>Здравствуйте, A.Lokotkov, Вы писали:
AL>>Здравствуйте, anton20vlad, Вы писали:
AL>>Отвратительный Костыль:
D>[Skip] AL>> requestInfo.repackTapes.destinationTape.reserve(512);
D>Согласен, вариант решения, но тут куча факторов — Debug/Release, версия студии, версия STL. Придется ему попотеть пока все сложится D>Может как то аллокатор перенаправить, на кучу из DLL?
Здравствуйте, 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)
Здравствуйте, anton20vlad, Вы писали:
A>Похоже что подменяют... Всё та же ошибка. Сейчас постараюсь выложить хедер.
Учитывая степень запущенности случая, они могут там у себя запросто использовать копирующее присваивание, сгенеренное компилятором, всему интерфейсному объекту, в результате чего ни один костыль не поможет в принципе.
D>diva.lib есть? Я так смотрю тут методы класов экспортируются. D>Тут нужно будет слинковаться с этой либой. Хотя честно не понимаю как они думали использовать STL в API, экспорта на эти класы нет. D>Вы вообще можете ее коректно использовать просто в CPP проэкте? D>Какие у вас возможности линковаться с этой библиотекой? Возможна ли статическая линковка (no DLL)
Мне нужно использовать это Апи в Делфи приложении. Вариант с++ отпадает. Экспортируемые параметры функций в атой АПИшной библиотеке мягко говоря не стандартны, поэтому из Делфей я эти функции использовать просто не могу. Поэтому пишу обёртку для вот например getRequestInfo. К обёрточной библиотеке прикручиваю АПИшную так:
#pragma comment(lib, "DIVAapi.lib")
Проблема стала только с getRequestInfo. С отстальными (partialRestore например) подобных трудностей не возникло. Всё работает без проблем. Как по Вашему, есть ли ещё какие-то возможности справится с возникшей трудностью?
Здравствуйте, Danchik, Вы писали:
D>Может как то аллокатор перенаправить, на кучу из DLL?
Аллокатор надо передавать каждой stl-строке при конструировании интерфейсного объекта в клиентском коде перед тем вызовом. Тогда, если авторы не используют копирующее присваивание для интерфейсного объекта, костыль может помочь.
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 и я бы с такой уверенностью что все гуд не говорил. Вылетит позже.
AL>Здравствуйте, Danchik, Вы писали:
D>>Может как то аллокатор перенаправить, на кучу из DLL?
В предыдущем посте я погорячился. На самом деле проблем бы не было вообще, если бы для того интерфейсного объекта в DLL авторы бы сделали явные конструктор и деструктор и экспортировали их из DLL. Тогда всегда вызывались бы они, и правильно освобождали память.
Последний вариант: завести интерфейсный объект статически в клиентском коде и реюзать взякий раз, когда нужно обратиться к той функции.
anton20vlad пишет:
> Спасибо, за ответ. У меня нет вариантов — так сваяли библиотеку апишную > буржуи. Я честно говоря уже все мозги сломал как решить эту проблему?
А никак ты её не решишь. Тебе надо использовать то же CRT, что и у этой
библиотеки. Видимо, это в данном случае MSVCRT, поскольку кроме неё и
дельфы уже там ничего не осталось. А это, видимо, невозможно в билдере.
Да > я понимаю что оно в разных местах выделяется и высвобождается, но в этом > конкретном случае что нужно сделать чтобы избавится от ошибки?
anton20vlad пишет:
> AL>Я правильно понимаю, что их API тоже выставлено из их DLL и нет > доступа к исходникам? > AL>P.S. Кстати, явный вызов деструкторов однозначно идет в сад. > > Правильно. Исходников нет и не будет (. Явный вызов деструкторов от > отчаяния...
Явный вызов деструктора ничем не плох, но он вам не освободит
память и он может быть вообще недоступен из другого модуля (.dll), это же STL,
темплейты....
Здравствуйте, anton20vlad, Вы писали:
A>Проблема решилась VirtualAlloc, VirtualFree. Всё красиво и тихо отрабатывает. Только вот не уверен что это правильное решение )
Здравствуйте, A.Lokotkov, Вы писали:
AL>Здравствуйте, anton20vlad, Вы писали:
A>>Проблема решилась VirtualAlloc, VirtualFree. Всё красиво и тихо отрабатывает. Только вот не уверен что это правильное решение )
AL>Как именно оно решилось?
Здравствуйте, A.Lokotkov, Вы писали:
AL>Здравствуйте, anton20vlad, Вы писали:
A>>Никаких ошибок с памятью, отрабатывает как надо.
AL>Вы можете рассказать, почему Вы сделали именно так и почему оно перестало падать?
Перебирал варианты ) и сделал так. А вот насчёт почему перестало падать...думаю что решился вопрос с тем где именно и кем выделяется и высвобождается память. Вы видите какую-то ошибку в коде?
Здравствуйте, anton20vlad, Вы писали:
A>Перебирал варианты ) и сделал так. А вот насчёт почему перестало падать...думаю что решился вопрос с тем где именно и кем выделяется и высвобождается память. Вы видите какую-то ошибку в коде?
Конструктор и деструктор интерфейсного объекта на клиентской стороне теперь не вызываются. Поскольку не вызывается конструктор, для каждой stl-строки внутри интерфейсного объекта DIVA_REQUEST_INFO не создается небольшой умолчательный буфер, -- там будет NULL. Когда несконструированный интерфейсный объект с несконструированными строками внутри передается в их dll, stl почему-то не падает. Может быть, потому что, увидев NULL, аллокирует буфера в строках на стороне dll. Если это так, то после того, как Вы делаете VirtualFree на своей стороне, память, выделенная под буфера строк, никогда не будет освобождена (по-крайней мере, до выгрузки выделившей ее dll). Для такого решения необязательно делать именно VirualAlloc/VirualFree, я думаю, с тем же успехом можно было бы написать как-нибудь так:
Здравствуйте, MasterZiv, Вы писали:
>> Динамический рантайм мог бы спасти отца русской демократии MZ>у него он и так динамический. Другого не бывает в .dll.
Здравствуйте, MasterZiv, Вы писали:
MZ>g_i пишет:
>> Динамический рантайм мог бы спасти отца русской демократии
MZ>у него он и так динамический. Другого не бывает в .dll.
Да, действительно так тоже работает без ошибок. Мне всё-таки важно, чтобы память занятая строками высвобождалась. Признаюсь, что настолько глубоко я темой не владею, поэтому хочу спросить Вашего совета. Мне предложили ещё несколько способов(цитирую):
1. Отказываешься от размещения класса в стеке, вместо этого, пусть её для тебя создаёт и уничтожает библиотека(в стиле С):
Foo* foo = AllocFoo();
DoSmth(foo);
FreeFoo(foo);
2. Класс ты ж сам придумал?(Тут не совсем так...его буржуи придумали). Тогда задай для его небезопасных членов собственный алокатор. Тогда вместо wstring придётся взять basic_string<>. Словом, намаешься, но такой класс можно будет размещать даже в стеке. Это больше по С++.
3. Ещё есть одно простое решение. По идее, тебе достаточно написать (пусть и пустой) деструктор(Как я понял для класса DIVA_REQUEST_INFO). Таким образом его код будет находится в библиотеке, следовательно, и освобождаться память будет кодом библиотеки. Это только отсрочка. Так как нужно будет проследить, чтобы никто другой не работал с твоим wstring непосредственно. Правда для этого тоже можно подмутить методы-аксесоры.
Мне кажется самое простое это 3й вариант. Правда как я понимаю, память всё-равно не высвободится, так как деструктор пустой? И ещё один вопрос: для чего нужно "подмутить методы-аксесоры"? Это я недопонял.
Здравствуйте, Odi$$ey, Вы писали:
OE>Здравствуйте, MasterZiv, Вы писали:
>>> Динамический рантайм мог бы спасти отца русской демократии MZ>>у него он и так динамический. Другого не бывает в .dll.
OE>/MT для при сборке .dll уже отменили?
В продолжение темы с пустым деструктором и про "подмутить методы аксесоры". Судя по всему, их таки надо подмутить так как ошибка никуда не делась...Правда я не понимаю что имеется в виду.
Здравствуйте, Аноним, Вы писали:
А>[/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;
}
Здравствуйте, MasterZiv, Вы писали:
MZ>g_i пишет:
>> MZ>у него он и так динамический. Другого не бывает в .dll. >> >> Судя по описанию проблемы, это не так.
MZ>Тем хуже для него. Так может только в этом и проблема ? MZ>А вообще, какой рантайм "Дельфа" использует ?
Тут до Delphi еще далеко, он CPP не может заставить работать.
Здравствуйте, anton20vlad, Вы писали:
A>Здравствуйте, Odi$$ey, Вы писали:
OE>>Здравствуйте, MasterZiv, Вы писали:
>>>> Динамический рантайм мог бы спасти отца русской демократии MZ>>>у него он и так динамический. Другого не бывает в .dll.
OE>>/MT для при сборке .dll уже отменили?
A>/MT при сборке имеется.
У вас имеется dll. С каким рантаймом собрана эта dll? Со статическим? Заказать пересборку с динамическим можно?
Важно чтобы оба модуля (клиент и длл) использовали один тип рантайма. Затем важно чтобы они могли работать с одной и той-же версией рантайм dll.
Сам себя запутал.
DLL собираешь ты. Используй динамический рантайм если клиент сможет использовать динамический рантайм.
Если нет — не используй string. Вообще, откуда проблема с деструктором std::string если ты утверждаешь, что допустимы только сишные экспорты?
Здравствуйте, anton20vlad, Вы писали:
A>Спасибо, за ответ. У меня нет вариантов — так сваяли библиотеку апишную буржуи. Я честно говоря уже все мозги сломал как решить эту проблему? Да я понимаю что оно в разных местах выделяется и высвобождается, но в этом конкретном случае что нужно сделать чтобы избавится от ошибки?
Я правильно понимаю, что, проблема состоит только в том, что приложение валится, когда дело доходит до разрушения локальной DIVA_REQUEST_INFO requestInfo; внутри WDIVA_getRequestInfo()?
Ваша обертка и буржуйский код используют совместимые версии STL, т.е. строки в структуре requestInfo инициализирются корректно?
Если все так, то можно так попробовать проблему решить:
Похожее решение тут уже предлагали, только там буфер был локальный, а тут статический. Смысл в статическом буфере в том, что память под строки не будет утекать.
Если у вас приложение многопоточное, то вместо простого глобального статического буфера можно использовать буфер из TLS.
g_i пишет:
> У вас имеется dll. С каким рантаймом собрана эта dll? Со статическим? > Заказать пересборку с динамическим можно?
Если какая-то DLL собрана со статическим рантаймом, то её, за исключением очень
редких случаев очень грамотного проектирования интерфейсов этой .DLL,
которые в жизни почти не встречаются, и к числу которых данная .DLL явно НЕ
относится, МОЖНО СРАЗУ ЖЕ ВЫКИНУТЬ НА ПОМОЙКУ, как непригодную к использованию.
Danchik пишет:
> Тут до Delphi еще далеко, он CPP не может заставить работать.
Да я вообще не очень понимаю, что он там делать собирается,
как он это дело в дельфу вставит ? Легче наверное новый язык
программирования изучить, чем это вот сделать.
Здравствуйте, MasterZiv, Вы писали:
MZ>Если какая-то DLL собрана со статическим рантаймом, то её, за исключением очень MZ>редких случаев очень грамотного проектирования интерфейсов этой .DLL, MZ>которые в жизни почти не встречаются, и к числу которых данная .DLL явно НЕ MZ>относится, МОЖНО СРАЗУ ЖЕ ВЫКИНУТЬ НА ПОМОЙКУ, как непригодную к использованию.
Да, конечно. Если у тебя более одного Win32 модуля в системе,
все эти модули должны иметь один экземпляр CRTL. Иначе (хотя бы)
все нереентерабельные функции типа strtok ТУПО НЕ БУДУТ РАБОТАТЬ,
если они будут вызваны из двух РАЗНЫХ win32 модулей. Потому
что все статические данные CRTL должны быть в одном экземпляре
у приложения (думаю, напоминать, что они есть, не нужно: таблицы
открытых файлов, стандартные потоки ввода-вывода, локали и т.п.).
Это невозможно при сборке со статической CRTL --
их будет как минимум 2 у нескольких Win32-модулей.
Есть конечно и исключения, о которых я говорил — это если
всё использование CRT одним модулем замыкается только внутри одного
модуля. Для этого нужно специальным образом этот модуль проектировать.
Здравствуйте, MasterZiv, Вы писали:
>> обосновать можешь?
MZ>Да, конечно. Если у тебя более одного Win32 модуля в системе, все эти модули должны иметь один экземпляр CRTL. Иначе (хотя бы) все нереентерабельные функции типа strtok ТУПО НЕ БУДУТ РАБОТАТЬ, если они будут вызваны из двух РАЗНЫХ win32 модулей.
strtok действительно использует статические переменные при разборе и поэтому нельзя внутри цикла с strtok применять эту функцию к другой строке. Но каким образом эта ситуация еще может ухудшиться из-за разных CRT в разных модулях — я не вижу. Скорее уж наоборот — теперь можно будет сделать внутри цикла strtok одного модуля вызов функции другого модуля внутри которого будет свой strtok — и при этом их статические переменные никак друг на друга не повлияют.
Здравствуйте, MasterZiv, Вы писали:
MZ>Danchik пишет:
>> Тут до Delphi еще далеко, он CPP не может заставить работать.
MZ>Да я вообще не очень понимаю, что он там делать собирается, MZ>как он это дело в дельфу вставит ? Легче наверное новый язык MZ>программирования изучить, чем это вот сделать.
Если изменит интерфейс экспортируемых функций то очень просто. Да хоть COM
Odi$$ey пишет:
> строке. Но каким образом эта ситуация еще может ухудшиться из-за разных > CRT в разных модулях — я не вижу. Скорее уж наоборот — теперь можно > будет сделать внутри цикла strtok одного модуля вызов функции другого
У тебя какое-то очень наивное представление о CRTL. Выводы о возможности
улучшения её работы -- тоже. Что же, на каждый поток по CRT будем заводить,
или на каждую функцию ?
Здравствуйте, MasterZiv, Вы писали:
>> строке. Но каким образом эта ситуация еще может ухудшиться из-за разных >> CRT в разных модулях — я не вижу. Скорее уж наоборот — теперь можно >> будет сделать внутри цикла strtok одного модуля вызов функции другого
MZ>У тебя какое-то очень наивное представление о CRTL. Выводы о возможности MZ>улучшения её работы -- тоже. Что же, на каждый поток по CRT будем заводить, MZ>или на каждую функцию ?
давай не будем обо всем сразу — потоки, наивные представления и проч. bla-bla-bla, можешь показать как у strtok съезжает крыша в dll со статической CRT?