У меня есть DLL C и вы хотите называть его из Delphi XE3 Update 2. Любопытно, что в моем проекте, называющем его динамически, он отличается от его статического старта. Вот «минимальный» код для воспроизведения (я изменил Lib/functionnames):Dynamic vs. Static DLL Linking is different
program testProject;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils, System.classes, Windows;
function keylist_open (keylist: PPointer): Integer; external 'libLib';
var
Handle: HINST;
DLLName: PChar = 'libLib.dll';
type
Tkeylist_open = function(keylist: PPointer): Integer; stdcall;
const
keylist_openDynamic: Tkeylist_open = nil;
var
keylist: Pointer;
begin
Handle := LoadLibrary(DLLName);
if Handle = 0 then
Exit;
@keylist_openDynamic := GetProcAddress(Handle, 'keylist_open');
keylist_open(@keylist);
if (keylist = nil) then
Writeln('static: keylist is nil');
keylist_openDynamic(@keylist);
if (keylist = nil) then
Writeln('dynamic: keylist is nil');
end.
Выход
static: keylist is nil
Это означает, что вызов функции динамически отличается от статически. keylist действительно инициализируется правильно, называя его динамически. смотрит в сгенерированный код на ассемблере я понимаю, что переменная 'KeyList' помещается в регистр EAX:
testProject.dpr.34: keylist_open(@keylist);
004D16A2 B804B04D00 mov eax,$004db004
004D16A7 E8ECC6FFFF call keylist_open
затем
testProject.dpr.12: function keylist_open (keylist: PPointer): Integer; external 'libLib';
004CDD98 FF255CC54D00 jmp dword ptr [$004dc55c]
и другой прыжок
libLib.keylist_open:
5B364508 E903A23D00 jmp $5b73e710
, но затем dll (я не знаю, какая функция это, какая-то точка входа или подпрограмма), есть
5B73E710 55 push ebp
5B73E711 8BEC mov ebp,esp
5B73E713 81ECDC000000 sub esp,$000000dc
5B73E719 53 push ebx
5B73E71A 56 push esi
5B73E71B 57 push edi
5B73E71C 8DBD24FFFFFF lea edi,[ebp-$000000dc]
5B73E722 B937000000 mov ecx,$00000037
5B73E727 B8CCCCCCCC mov eax,$cccccccc
...
кажется, что параметр eax перезаписан в eax. две строки позже код для динамического вызова:
testProject.dpr.37: keylist_openDynamic(@keylist);
004D16CE 6804B04D00 push $004db004
004D16D3 FF15F0564D00 call dword ptr [$004d56f0]
прыжки
libLib.keylist_open:
5B364508 E903A23D00 jmp $5b73e710
и, таким образом, тот же код. Но поскольку параметр теперь не хранится в eax, перезапись eax не имеет значения.
звоните, кто-нибудь проливает свет здесь, что происходит неправильно, то есть что не так с моим статическим кодом и почему?
крысы! это оно! не должен был полагаться на delphi-учебник, который связывал dll delpih, поэтому мысль stdcall предназначена только для динамической компоновки: (... большое спасибо !! – complexM