|
Вопрос # 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]:
Спасибо! Разобрался - теперь вроде все работает.
|
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|