我的DLL如何检测它是隐式还是显式加载?
示例MyTestDll.dll
library MyTestDll;
uses SimpleShareMem, Windows, Dialogs;
procedure DetectMethodDllLoad: bool;
begin
// ?????
// need to detect loading method - implicit or explicit
end;
procedure MyTest; stdcall;
begin
if DetectMethodDllLoad then
ShowMessage('Working Program1 (implicit dll load)')
else
ShowMessage('Working Program2 (explicit dll load)');
end;
exports MyTest;
begin
end.
Program1.exe(隐式dll加载)
procedure MyTest; stdcall; external 'MyTestDll.dll' Name 'MyTest';
procedure TForm1.Button1Click(Sender: TObject);
begin
MyTest;
end;
Program2.exe(显式dll加载)
type
TMyTest = procedure; stdcall;
procedure TForm1.Button1Click(Sender: TObject);
var
MyTest: TMyTest;
H: HModule;
begin
H := LoadLibrary('MyTestDll.dll');
if H = 0 then
exit;
@MyTest := GetProcAddress(H, 'MyTest');
if Assigned(MyTest) then
MyTest;
FreeLibrary(H);
end;
如何实施DetectMethodDllLoad
?
答案 0 :(得分:3)
如果您可以创建DllMain过程,则DLL_PROCESS_ATTACH调用的lpReserved参数将告诉您加载是静态还是动态。
http://msdn.microsoft.com/en-us/library/ms682583%28VS.85%29.aspx
你当然可以在C中这样做。我不知道Delphi中是否可行。
答案 1 :(得分:1)
这是一个非常好的教程,包含2种方法,静态和动态:
Static vs. Dynamic Dynamic Link Library Loading - A Comparison
答案 2 :(得分:-1)
谢谢Harry Johnston !!! :)
library MyTestDll;
uses SimpleShareMem, Windows, Dialogs;
type
PDllEntryPointFrame = ^TDllEntryPointFrame;
TDllEntryPointFrame = packed record
hModule: THandle; // DLL module handle
dwReason: DWord; // reason for calling DLLEntryPoint function of DLL
bStatic: LongBool; // TRUE if DLL is loading/unloading satically, FALSE - dinamically
end;
function DetectMethodDllLoad: bool;
asm
mov edx, [hInstance]
mov eax, ebp
@@nextframe:
cmp [eax + $08].TDllEntryPointFrame.hModule, edx
je @@found
mov eax, [eax]
jmp @@nextframe
@@found:
mov eax, [eax + $08].TDllEntryPointFrame.bStatic
end;
procedure MyTest; stdcall;
begin
...
end;
exports MyTest;
begin
if DetectMethodDllLoad then
ShowMessage('Working Program1 (implicit dll load)')
else
ShowMessage('Working Program2 (explicit dll load)');
end.
P.S。 Delphi XE中的System.TDLLProcEx 无法正常工作!
library MyTestDll;
....
procedure MyDLLProcEx(Reason:integer;x:pointer);
begin
if x=nil then showmessage('dyn') else showmessage('stat');
end;
begin
DLLProcEx:=@MyDLLProcEx;
end;
x = nil总是:(