| 
| 
 | Вопрос # 3 106/ вопрос открыт / | 
 |  Здравствуйте, эксперты! Есть рабочий код (внутри) , который срабатывает в 100% случаях, но если я его помещаю в DLL то каждый второй вызов сопровождается ошибкой. В чем может быть проблема? А то у меня есть еще пару функций которые также ведут себя в DLL. Приложение:Переключить в обычный режим  function GetVersion: string;  StdCall; var   VerInfoSize: DWORD;   VerInfo: Pointer;   VerValueSize: DWORD;   VerValue: PVSFixedFileInfo;   Dummy: DWORD; begin                        TRY   VerInfoSize := GetFileVersionInfoSize(PChar(ParamStr(0)), Dummy);   GetMem(VerInfo, VerInfoSize);   GetFileVersionInfo(PChar(ParamStr(0)), 0, VerInfoSize, VerInfo);   VerQueryValue(VerInfo, '', Pointer(VerValue), VerValueSize);   with VerValue^ do   begin     Result := IntToStr(dwFileVersionMS shr 16);     Result := Result + '.' + IntToStr(dwFileVersionMS and $FFFF);     Result := Result + '.' + IntToStr(dwFileVersionLS shr 16);     Result := Result + '.' + IntToStr(dwFileVersionLS and $FFFF);   end;                        EXCEPT                          END;    FreeMem(VerInfo, VerInfoSize); end;   exports GetVersion index 31;  Function GetVersion: string; StdCall; external 'KASFILES.dll' index 31; label72.Caption:=GetVersion; 
|  |   Вопрос задал: gm44 (статус: Посетитель)Вопрос отправлен: 20 августа 2009, 11:55
 Состояние вопроса: открыт, ответов: 1.
 |  Ответ #1. Отвечает эксперт: Вадим К Здравствуйте, gm44!Сколько пишут - использвовать string для передачи с dll плохая затея. Для решения надо
 - использовать ShareMem. добавить в все файлы с расширением dpr в список uses его самым первым. можно использовать FastMM вместо него, если версия делфи "старая".
 - использовать юникодные (широкие строки, они же widestring).
 - использовать указатели и передавать указатель на буфер - массив символов.
 - не использовать строки вообще.
 Почему так происходит? потому что у длл и основного приложения разные менеджеры памяти.
 
|  | Ответ отправил: Вадим К (статус: Академик)Время отправки: 20 августа 2009, 12:19
 Оценка за ответ: 5
 |  
 Мини-форум вопросаВсего сообщений: 3; последнее сообщение — 20 августа 2009, 14:32; участников в обсуждении: 2. 20 августа 2009, 12:10: Вопрос перемещён из тематического раздела Delphi » Общие вопросы по программированию в раздел Delphi » Работа с компонентами и библиотеками модератором Ерёмин А.А. Причина: вопрос о DLL 
|   | gm44 (статус: Посетитель), 20 августа 2009, 12:35 [#1]:Но тогда не понятно почему другие функции с использованием string нормально работают в DLL? Например {Узнать системный диск}
 Function GetSYSTEMDRIVE: string; StdCall;
 begin
 result:=copy(GetWind, 1,3);
 end;
 
 отробатывает нормально...
 |  
|   | Вадим К (статус: Академик), 20 августа 2009, 12:54 [#2]:Есть такое понятние - UB. - неопределённое поведение. Один раз работает, второй - нет. и можно конечно разобраться почему не работает или работает в каждом конкретном случае, но оно того не стоит. Вы же не ездите, как некоторые каскадёры на велосипеде без переднего колеса. 
 А в данном примере работает, потому что размер передаваемой строки - 4 байта (3 байта сама строка и байт длины). А вот почему так - долго рассказывать. Для начала надо понять как память вообще выделятся и расходуется.
 Галочка "подтверждения прочтения" - вселенское зло. |  
|   | gm44 (статус: Посетитель), 20 августа 2009, 14:32 [#3]:Спасибо! Разобрался - теперь вроде все работает. |  Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте. |