Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 3 106

/ вопрос открыт /

Здравствуйте, эксперты! Есть рабочий код (внутри) , который срабатывает в 100% случаях, но если я его помещаю в DLL то каждый второй вызов сопровождается ошибкой. В чем может быть проблема? А то у меня есть еще пару функций которые также ведут себя в DLL.

Приложение:
  1.  
  2. function GetVersion: string; StdCall;
  3. var
  4. VerInfoSize: DWORD;
  5. VerInfo: Pointer;
  6. VerValueSize: DWORD;
  7. VerValue: PVSFixedFileInfo;
  8. Dummy: DWORD;
  9. begin
  10. TRY
  11. VerInfoSize := GetFileVersionInfoSize(PChar(ParamStr(0)), Dummy);
  12. GetMem(VerInfo, VerInfoSize);
  13. GetFileVersionInfo(PChar(ParamStr(0)), 0, VerInfoSize, VerInfo);
  14. VerQueryValue(VerInfo, '', Pointer(VerValue), VerValueSize);
  15. with VerValue^ do
  16. begin
  17. Result := IntToStr(dwFileVersionMS shr 16);
  18. Result := Result + '.' + IntToStr(dwFileVersionMS and $FFFF);
  19. Result := Result + '.' + IntToStr(dwFileVersionLS shr 16);
  20. Result := Result + '.' + IntToStr(dwFileVersionLS and $FFFF);
  21. end;
  22. EXCEPT
  23.  
  24.  
  25. END;
  26. FreeMem(VerInfo, VerInfoSize);
  27. end;
  28.  
  29. exports GetVersion index 31;
  30.  
  31.  
  32. Function GetVersion: string; StdCall; external 'KASFILES.dll' index 31;
  33.  
  34. label72.Caption:=GetVersion;
  35.  


gm44 Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: 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

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

gm44 (статус: Посетитель), 20 августа 2009, 14:32 [#3]:

Спасибо! Разобрался - теперь вроде все работает.

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:33
Выполнено за 0.03 сек.