2014-10-09 53 views
-1

我有一个dll它定义了一个简单的函数来显示一个消息:动态地把手不DLEPHI在DLL中定义的函数

library testdll; 

uses SysUtils, Classes, Dialogs; 

{$R *res} 

procedure ShowDll;stdcall; 
begin 
    ShowMessage('ShowDLL testdll.dll'); 
end; 

exports ShowDLL; 
begin 
end. 

我的主文件调用这个DLL动态地使用此过程:

我定义了一个新的类型:

type 
    testdll = procedure;stdcall; 

然后在我的按钮单击事件:

procedure TForm1.Button1Click(Sender:TObject); 
var 
    dllHandle: THandle; //Don't use Cardinal; it's limited to 32-bits 
    test : testdll; 
begin 
    dllHandle := LoadLibrary('testdll.dll'); 
    if dllHandle <> 0 then 
    begin 
    @test := GetProcAddress(dllHandle,'ShowDLL'); 
    if Assigned(test) then 
     ShowDLL 
    else 
     ShowMessage('Func not found'); 
    end 
    else 
     ShowMessage('dll not found'); 
end; 

这有效。但我不知道是否可以用我的dll处理未定义的函数。我的目的是调用一个函数,而不知道它是否会在我的dll中定义。所以我想让dll告诉我函数是否存在。

例如,在这里我只有一个ShowDLL程序。如果我调用另一个不存在的方法,它会显示从我的主应用程序'Func not found'。但我会让我的dll告诉我这一点。这可能吗?如果是的话,我怎么能达到这个要求?

编辑:我不能修改主要功能,这只是一个测试。在我的最终版本中将只有dll。因此,将所有功能导出到我的主应用程序中是不可能的。这就是为什么我想知道ID单独的DLL可以处理它,而不是在我的主应用程序中这样做,我不能这样做。

我没有访问主应用程序来修改其中的任何代码。我只知道将在这个应用程序中使用的函数是什么,以后我将使用exports声明在我的dll中导出。所以我试图实现的是如果可能的话,用dll捕获未定义的函数。

+2

这没有任何意义。 'kernel32的'GetProcAddress'。dll'已经告诉你函数是否存在于导出表中。 – 2014-10-09 08:10:50

+0

但是,如果函数不存在,它将返回零。我想返回其他东西,但从DLL,而不是从GetProcAdresse,这是不可能的,除非大卫的答案 – user28470 2014-10-09 08:32:07

+0

然后滚动自己的表与名称/指针对和魔术导出的函数,它返回函数的名称和*别的*当名称没有找到...是你想要的吗? – 2014-10-09 10:29:45

回答

3

您的代码已经演示了如何检测导出的存在。即致电 GetProcAddress并将结果与​​ nil进行比较。

您可以通过延迟加载来减少锅炉板码的数量。这基本上可以让编译器生成执行检查的代码。这依赖于delayed关键字。

procedure testdll; stdcall; 
    external 'testdll.dll` delayed; 

当您调用此函数时,如果找不到,则会引发异常。事实上,这种行为可以进行定制,如文档中描述: http://docwiki.embarcadero.com/RADStudio/en/Libraries_and_Packages#Delayed_Loading

更新

在这个答案你指出可执行文件不能被改变的注释。在这种情况下,如果功能丢失,将显示您希望避免的消息。你问是否可以通过DLL来处理丢失的导出,但这是不可能的。当你调用GetProcAddress时,DLL中没有代码被执行。所有处理都是通过读取其PE元数据在DLL外部完成的。

明显的结论是DLL必须导出函数。如果真正的DLL没有,请将另一个DLL放在其位置。使用导出函数的插入程序DLL。如果真正的DLL导出函数,则通过委托给真正的DLL来实现函数。不管做什么,都可以做其他事情。

+0

但是这使用主要的应用来捕捉未定义的函数。有没有可能与dll做到这一点?就像从dll'函数中获取消息不存在'我要求这个知道我是否可以使用类似的东西来执行特定的代码,如果被调用的过程/函数不存在,就像默认函数一样。我无法修改应用程序。这就是为什么我问我们是否可以用dll执行此操作 – user28470 2014-10-09 06:17:34

+0

在我的主应用程序中只有一个LoadLibrary和一个GetProcAddress。我不能做更多的事情,也不会更少 – user28470 2014-10-09 06:18:48

+0

为什么你要等到有人回答这个问题?现在宣布主机可执行文件是你的,你可以改变这个问题。 – 2014-10-09 06:21:11