Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

глюк?

2 views
Skip to first unread message

Alexey Fayans

unread,
Dec 2, 2005, 1:55:15 PM12/2/05
to
Hi there, All!

Есть интерфейс для взаимодействия с библиотекой. Примерно такой:

=== Starting UnRAR.pas ===
{$IFDEF Open32}
{&cdecl+}
{$ELSE}
{&StdCall+}
{$ENDIF Open32}
{&AlignRec+,SmartLink+,OrgName+,X+,Z+,Use32-}

unit UnRAR;

interface

[...]

function RAROpenArchive(var ArchiveData: RAROpenArchiveData): THandle;

[...]

implementation

function RAROpenArchive(var ArchiveData: RAROpenArchiveData): THandle;
external 'unrar.dll' name 'RAROpenArchive';

[...]

end.
=== End of UnRAR.pas ===

Есть программа, которая юзает этот юнит:

=== Starting rartest.pas ===
uses
Windows,
Strings,
UnRAR;

var
Data: RAROpenArchiveData;
HeaderData: RARHeaderData;
Handle: THandle;
PathBuf: array[0..255] of Char;
N: Longint;

begin
FillChar(Data, SizeOf(Data), #0);
Data.ArcName := StrPCopy(@PathBuf, 'test.rar');
Data.OpenMode := RAR_OM_EXTRACT;
Data.CmtBuf := nil;
Handle := RAROpenArchive(Data);
WriteLn('Open archive result: ', Data.OpenResult);
if Data.OpenResult = 0 then
repeat
FillChar(HeaderData, SizeOf(HeaderData), #0);
N := RARReadHeader(Handle, HeaderData);
if N = 0 then
begin
Write('Testing ' + StrPas(HeaderData.FileName) + '..');
if RARProcessFile(Handle, RAR_TEST, nil, nil) = 0 then
WriteLn('OK')
else
WriteLn('FAIL');
end;
until N <> 0;
RARCloseArchive(Handle);
end.
=== End of rartest.pas ===

Программа нормально собирается и работает, если собирать с ключом -b. Если
собирать с ключом -m, программа не запускается, если юнит UnRAR был
скомпилирован до этого. Если поглядеть в код программы, в ней вообще
отсутствует упоминание об unrar.dll. Это глюк компилятора? Или фича? Или я
что-то не так делаю?

Еще есть предположение, что этот эффект можно победить, создав библиотеку
импорта, как это сделано для kernel32.dll и прочих стандартных. Hо это какой-то
ненормальный путь, мне кажется.

И еще, очень интересный момент. Если добавить {$D+} в UnRAR.pas - проблема
исчезает. Мистика какая-то.

ЗЫ: настройки компилятора:

=== Starting |vpcc ===
AlignCode- Code alignment Open32- Open32 compatibility
AlignData- Data alignment Optimise+ Enable optimisations
AlignRec- Field alignment OrgName- Original names
Asm- Assembler output P- Open string params
B- Full boolean eval PureInt- Pure interface unit
Cdecl- C language calls Q- Overflow checking
Comments- Nested comments R- Range checking
D- Debug information S- Stack checking
Delphi+ Enable Delphi syntax SmartLink+ Create .LIB file
Far16- Far16 Pascal calls Speed- Optimise for speed
Frame+ Stack frame for asm subprgs StdCall- StdCall calls
G3- 386 instructions T- Typed pointers
G4- 486 instructions Use32- Include Use32 unit
G5+ P5 instructions V+ Strict var-strings
H- Huge strings W- Generate stack frames
I- I/O error checking X+ Extended syntax
J+ Writable consts Z- DWord-sized enums
LocInfo- Location information Zd- Line numbers in .OBJ/.LIB
M- Runtime type info
=== End of |vpcc ===


Dmitry Zavalskov

unread,
Dec 2, 2005, 6:05:17 PM12/2/05
to
Hi,Alexey!

02 Dec 05 21:55, Alexey Fayans wrote to All:
AF> Программа нормально собирается и работает, если собирать с ключом -b.
AF> Если собирать с ключом -m, программа не запускается, если юнит UnRAR
AF> был скомпилирован до этого. Если поглядеть в код программы, в ней
AF> вообще отсутствует упоминание об unrar.dll. Это глюк компилятора? Или
AF> фича? Или я что-то не так делаю?
Это "фича" компилятора. Он не сохраняет в юнитах упоминание о dll.
AF> Еще есть предположение, что этот эффект можно победить, создав
AF> библиотеку импорта, как это сделано для kernel32.dll и прочих
AF> стандартных. Hо это какой-то ненормальный путь, мне кажется.
Ага. Вот именно так и лечится. Пишешь


function RAROpenArchive(var ArchiveData: RAROpenArchiveData):THandle;

external;
и подключаешь в юнит библиотеку: {$L UNRAR.LIB}

Dmitry.

Sp0Raw

unread,
Dec 2, 2005, 6:51:12 PM12/2/05
to
AF> Есть интерфейс для взаимодействия с библиотекой. Примерно такой:

AF> === Starting UnRAR.pas ===
AF> {$IFDEF Open32}
AF> {&cdecl+}
AF> {$ELSE}
AF> {&StdCall+}
AF> {$ENDIF Open32}

Это вообще практически бесполезные ключи.

AF> {&AlignRec+,SmartLink+,OrgName+,X+,Z+,Use32-}

AF> unit UnRAR;

AF> interface

AF> [...]

AF> function RAROpenArchive(var ArchiveData: RAROpenArchiveData): THandle;

AF> [...]

AF> implementation

AF> function RAROpenArchive(var ArchiveData: RAROpenArchiveData): THandle;
AF> external 'unrar.dll' name 'RAROpenArchive';

Ты уверен, что нет проблем со стэком?

Тут не указано cdecl или stdcall;

unrardll написан под паскаль? Тот же алигн структур?

AF> [...]

AF> end.
AF> === End of UnRAR.pas ===

AF> Есть программа, которая юзает этот юнит:

AF> === Starting rartest.pas ===
AF> uses
AF> Windows,
AF> Strings,
AF> UnRAR;

AF> var
AF> Data: RAROpenArchiveData;
AF> HeaderData: RARHeaderData;
AF> Handle: THandle;
AF> PathBuf: array[0..255] of Char;
AF> N: Longint;

AF> begin
AF> FillChar(Data, SizeOf(Data), #0);
AF> Data.ArcName := StrPCopy(@PathBuf, 'test.rar');
AF> Data.OpenMode := RAR_OM_EXTRACT;
AF> Data.CmtBuf := nil;
AF> Handle := RAROpenArchive(Data);
AF> WriteLn('Open archive result: ', Data.OpenResult);
AF> if Data.OpenResult = 0 then
AF> repeat
AF> FillChar(HeaderData, SizeOf(HeaderData), #0);
AF> N := RARReadHeader(Handle, HeaderData);
AF> if N = 0 then
AF> begin
AF> Write('Testing ' + StrPas(HeaderData.FileName) + '..');
AF> if RARProcessFile(Handle, RAR_TEST, nil, nil) = 0 then
AF> WriteLn('OK')
AF> else
AF> WriteLn('FAIL');
AF> end;
AF> until N <> 0;
AF> RARCloseArchive(Handle);
AF> end.
AF> === End of rartest.pas ===

AF> Программа нормально собирается и работает, если собирать с ключом -b.

Что за ключ?

AF> Если собирать с ключом -m,

Что за ключ?

AF> программа не запускается, если юнит UnRAR
AF> был скомпилирован до этого. Если поглядеть в код программы, в ней
AF> вообще отсутствует упоминание об unrar.dll. Это глюк компилятора? Или
AF> фича? Или я что-то не так делаю?

Какую ошибку выводит?

unrar.dll не может отсутсвовать, он должен быть в importtable.

AF> Еще есть предположение, что этот эффект можно победить, создав
AF> библиотеку импорта, как это сделано для kernel32.dll и прочих
AF> стандартных. Hо это какой-то ненормальный путь, мне кажется.

AF> И еще, очень интересный момент. Если добавить {$D+} в UnRAR.pas -
AF> проблема исчезает. Мистика какая-то.
AF> ЗЫ: настройки компилятора:

[ ... decrypted by Sp0Raw ... ]

Alexey Fayans

unread,
Dec 3, 2005, 1:02:59 AM12/3/05
to
Hi there, Dmitry!

On 03 Dec 2005 02:05 you wrote me:

AF>> Программа нормально собирается и работает, если собирать с ключом

AF>> -b. Если собирать с ключом -m, программа не запускается, если
AF>> юнит UnRAR был скомпилирован до этого. Если поглядеть в код
AF>> программы, в ней вообще отсутствует упоминание об unrar.dll. Это
AF>> глюк компилятора? Или фича? Или я что-то не так делаю?
DZ> Это "фича" компилятора. Он не сохраняет в юнитах упоминание о dll.

Плохая фича.. Ладно, будем извращаться.. Спасибо. :)

Кстати, а $L писать обязательно? Мне казалось, будет достаточно этот либ просто
положить в %VPBase%\lib.w32.


Alexey Fayans

unread,
Dec 3, 2005, 1:15:16 AM12/3/05
to
Hi there, Sp0Raw!

On 03 Dec 2005 02:51 you wrote me:

AF>> === Starting UnRAR.pas ===
AF>> {$IFDEF Open32}
AF>> {&cdecl+}
AF>> {$ELSE}
AF>> {&StdCall+}
AF>> {$ENDIF Open32}

SR> Это вообще практически бесполезные ключи.

Именно таким образом сделано в юните windows.

[...]
AF>> function RAROpenArchive(var ArchiveData: RAROpenArchiveData):

AF>> THandle;


AF>> external 'unrar.dll' name 'RAROpenArchive';

SR> Ты уверен, что нет проблем со стэком?
SR> Тут не указано cdecl или stdcall;

Оно задано глобально для всего файла. Если бы calling convention был
стандартный, были бы перепутаны параметры. А у меня все работает. :)

SR> unrardll написан под паскаль? Тот же алигн структур?

Я просто немного переделал дельфийный модуль, который шел в комплекте.
Структуры по крайней мере передаются как надо.

AF>> Программа нормально собирается и работает, если собирать с ключом

AF>> -b.
SR> Что за ключ?

build all

AF>> Если собирать с ключом -m,

SR> Что за ключ?

make modified

AF>> программа не запускается, если юнит UnRAR
AF>> был скомпилирован до этого. Если поглядеть в код программы, в ней
AF>> вообще отсутствует упоминание об unrar.dll. Это глюк компилятора?

AF>> Или фича? Или я что-то не так делаю?
SR> Какую ошибку выводит?

RTE216 или вообще ошибку инициализации.

SR> unrar.dll не может отсутсвовать, он должен быть в importtable.

HЕТУ ЕГО ТАМ. Причем только если собирать второй раз, не пересобирая UnRAR.pas.


Alexey Fayans

unread,
Dec 3, 2005, 2:52:37 AM12/3/05
to
Hi there, Dmitry!

On 03 Dec 2005 09:02 I wrote you:

AF> Кстати, а $L писать обязательно? Мне казалось, будет достаточно этот
AF> либ просто положить в %VPBase%\lib.w32.

Ага, уже вижу, что обязательно.


Sp0Raw

unread,
Dec 3, 2005, 7:27:29 AM12/3/05
to
AF>>> === Starting UnRAR.pas ===
AF>>> {$IFDEF Open32}
AF>>> {&cdecl+}
AF>>> {$ELSE}
AF>>> {&StdCall+}
AF>>> {$ENDIF Open32}
SR>> Это вообще практически бесполезные ключи.
AF> Именно таким образом сделано в юните windows.

Эти ключи не влияют на external объекты.

AF> [...]

AF>>> function RAROpenArchive(var ArchiveData: RAROpenArchiveData):
AF>>> THandle;
AF>>> external 'unrar.dll' name 'RAROpenArchive';
SR>> Ты уверен, что нет проблем со стэком?
SR>> Тут не указано cdecl или stdcall;

AF> Оно задано глобально для всего файла. Если бы calling convention был
AF> стандартный, были бы перепутаны параметры. А у меня все работает. :)


SR>> unrardll написан под паскаль? Тот же алигн структур?

AF> Я просто немного переделал дельфийный модуль, который шел в комплекте.
AF> Структуры по крайней мере передаются как надо.

AF>>> Программа нормально собирается и работает, если собирать с

AF>>> ключом -b.
SR>> Что за ключ?
AF> build all


AF>>> Если собирать с ключом -m,
SR>> Что за ключ?

AF> make modified

AF>>> программа не запускается, если юнит UnRAR
AF>>> был скомпилирован до этого. Если поглядеть в код программы, в

AF>>> ней вообще отсутствует упоминание об unrar.dll. Это глюк
AF>>> компилятора? Или фича? Или я что-то не так делаю?
SR>> Какую ошибку выводит?
AF> RTE216 или вообще ошибку инициализации.


SR>> unrar.dll не может отсутсвовать, он должен быть в importtable.

AF> HЕТУ ЕГО ТАМ. Причем только если собирать второй раз, не пересобирая
AF> UnRAR.pas.

Hу тебе вроде тут ответили чего-то. Хотя мне проблема не понятна :(

Sp0Raw

unread,
Dec 3, 2005, 7:26:52 AM12/3/05
to
AF>> Программа нормально собирается и работает, если собирать с ключом
AF>> -b. Если собирать с ключом -m, программа не запускается, если
AF>> юнит UnRAR был скомпилирован до этого. Если поглядеть в код
AF>> программы, в ней вообще отсутствует упоминание об unrar.dll. Это
AF>> глюк компилятора? Или фича? Или я что-то не так делаю?
DZ> Это "фича" компилятора. Он не сохраняет в юнитах упоминание о dll.

В чем глюк? Что-то я не понимаю сути проблемы :)

AF>> Еще есть предположение, что этот эффект можно победить, создав
AF>> библиотеку импорта, как это сделано для kernel32.dll и прочих
AF>> стандартных. Hо это какой-то ненормальный путь, мне кажется.

DZ> Ага. Вот именно так и лечится. Пишешь
DZ> function RAROpenArchive(var ArchiveData:
DZ> RAROpenArchiveData):THandle;
DZ> external;
DZ> и подключаешь в юнит библиотеку: {$L UNRAR.LIB}

To AF: предлагаю уйти от этого изврата и сделать динамическую линковку через
LoadLibrary/GetProcAddress

Alexey Fayans

unread,
Dec 4, 2005, 12:27:25 PM12/4/05
to
Hi there, Sp0Raw!

On 03 Dec 2005 15:26 you wrote Dmitry Zavalskov:

SR> To AF: предлагаю уйти от этого изврата и сделать динамическую линковку
SR> через LoadLibrary/GetProcAddress

Hадо будет подумать над этим.. Может и вторая проблема таким образом решится..


Alexey Fayans

unread,
Dec 4, 2005, 12:28:18 PM12/4/05
to
Hi there, Sp0Raw!

On 03 Dec 2005 15:26 you wrote Dmitry Zavalskov:

DZ>> Это "фича" компилятора. Он не сохраняет в юнитах упоминание о

DZ>> dll.
SR> В чем глюк? Что-то я не понимаю сути проблемы :)

Глюк в том, что в отлинкованном модуле, в котором прописаны функции dll как
external 'dllname.dll', не сохраняется упоминание о dll, которой эти функции
пренадлежат. И программа, собранная с таким юнитом, попросту неработоспособна.


Alexey Fayans

unread,
Dec 4, 2005, 12:33:26 PM12/4/05
to
Hi there, Sp0Raw!

On 03 Dec 2005 15:27 you wrote me:

SR>>> Это вообще практически бесполезные ключи.
AF>> Именно таким образом сделано в юните windows.

SR> Эти ключи не влияют на external объекты.

Дубль два. Именно так сделано в RTL модуле windows.pas. Там все виндовые
функции объявлены без модификатора stdcall. Hо я на всякий случай сделал как ты
говоришь, прописал везде stdcall - абсолютно то же самое. В любом случае,
модификатор stdcall можно прописывать только в интерфейсной части юнита. Ибо:

UnRAR.pas(148): Error 37: END expected
function RAROpenArchive; external; stdcall;
.............................................^

UnRAR.pas(148): Error 36: BEGIN expected
function RAROpenArchive; stdcall; external;
...................................^

AF>>>> программа не запускается, если юнит UnRAR
AF>>>> был скомпилирован до этого. Если поглядеть в код программы, в
AF>>>> ней вообще отсутствует упоминание об unrar.dll. Это глюк
AF>>>> компилятора? Или фича? Или я что-то не так делаю?
SR>>> Какую ошибку выводит?
AF>> RTE216 или вообще ошибку инициализации.
SR>>> unrar.dll не может отсутсвовать, он должен быть в importtable.
AF>> HЕТУ ЕГО ТАМ. Причем только если собирать второй раз, не

AF>> пересобирая UnRAR.pas.
SR> Hу тебе вроде тут ответили чего-то. Хотя мне проблема не понятна :(

Тут другая проблема появилась.. :)


Alexey Korop

unread,
Dec 5, 2005, 4:02:14 AM12/5/05
to
Привет, Alexey!

04.12.2005 в 20:28:09 Alexey Fayans написал к Sp0Raw:

DZ>>> Это "фича" компилятора. Он не сохраняет в юнитах упоминание о
DZ>>> dll.
SR>> В чем глюк? Что-то я не понимаю сути проблемы :)

AF> Глюк в том, что в отлинкованном модуле, в котором прописаны функции
AF> dll как external 'dllname.dll', не сохраняется упоминание о dll,
AF> которой эти функции пренадлежат. И программа, собранная с таким
AF> юнитом, попросту неработоспособна.
Hе может быть. Регулярно так описываю и всё работает. Пример:

function Register_Card (CardType:Word; card_num:Word):Smallint;stdcall;
...
function Register_Card; external 'Pci-Dask.dll' name 'Register_Card';

А что за VP у тебя? Помнится, с build 243 и у меня были какие-то странности
с функциями из dll, а после перехода на build 274 все проблемы исчезли.

С уважением, Alexey.

...В действительности всё совсем не так, как на самом деле.

Alexey Fayans

unread,
Dec 6, 2005, 5:32:42 AM12/6/05
to
Hi there, Alexey!

On 05 Dec 2005 12:02 you wrote me:

AF>> Глюк в том, что в отлинкованном модуле, в котором прописаны

AF>> функции dll как external 'dllname.dll', не сохраняется упоминание
AF>> о dll, которой эти функции пренадлежат. И программа, собранная с
AF>> таким юнитом, попросту неработоспособна.
AK> Hе может быть. Регулярно так описываю и всё работает. Пример:

Я тебе могу на мыло прислать юнит и программу, просто собери ее два раза с
ключом -m и посмотри, что из этого получится.

AK> function Register_Card (CardType:Word;
AK> card_num:Word):Smallint;stdcall;
AK> ...
AK> function Register_Card; external 'Pci-Dask.dll' name 'Register_Card';

AK> А что за VP у тебя? Помнится, с build 243 и у меня были какие-то
AK> странности с функциями из dll, а после перехода на build 274 все
AK> проблемы исчезли.

279.


0 new messages