使用动态路径指向DLL
我的问题是不导出函数,而是导入它。我确实知道函数和DLL都可以工作,因为我使用了硬编码的路径来指向DLL。使用动态路径指向DLL
这是目前工作:
function RoamingAppDataPath: String; external 'C:\Users\Peter\AppData\Roaming\ss\Application\ss.dll';
但是我需要指向同一个动态值的DLL所以我试图做的是
- 声明一个全局变量(的DLLPath:字符串)
- 分配的DLLPath值 - RoamingAppDataPath + '\ SS \应用程序\ ss.dll'
注意:RoamingAppDataPath是一个输出漫游应用程序数据文件夹路径的函数。
我试图运行的代码是:
function RoamingAppDataPath: String; external DLLPath;
当我编译代码,德尔福告诉我,这是需要一个常量表达式:
E2026 Constant expression expected
什么是围绕工作为了这?
你必须在运行时绑定,这意味着你需要使用的LoadLibrary和GetProcAddress:
var
lib: HMODULE;
RoamingAppDataPath: function: string;
lib := LoadLibrary(dllfilename);
if lib=0 then
RaiseLastOSError;
Pointer(RoamingAppDataPath) := GetProcAddress(lib, 'RoamingAppDataPath');
然后你就可以把它叫做:
radp := RoamingAppDataPath;
一些评论:
- 我不知道你为什么写这个函数时它存在于标准系统库中。
- 跨DLL边界使用字符串可能会失败。您需要使用ShareMem并确保所有代码都使用相同的Delphi版本构建。最好在调用代码中分配缓冲区。
更好使用SafeLoadLibrary或LoadLibraryEx – 2013-03-10 14:33:05
为什么这么说? LoadLibrary适用于很多用途。 – 2013-03-10 15:16:34
这是一个合适的答案,假设DLL可能在任何地方。 – 2013-03-10 18:21:19
即使您能够使用变量,也无处可以将值设置为DLLPATH,因为如果不能使用静态DLL,就不会使用初始化。 如果您想为DLL定义路径,您将不得不使用动态加载。
procedure Test;external 'Notexists.DLL';
var
Form2: TForm2;
implementation
{$R *.dfm}
procedure TForm2.Button1Click(Sender: TObject);
begin
test;
end;
initialization
Showmessage('Hallo'); // will never be seen if test is used.
你可以使用['delayed'](http://docwiki.embarcadero.com/RADStudio/XE3/en/Libraries_and_Packages#Delayed_Loading)指令来加载一个库当函数被调用时。尽管如您所说,这种情况是['dynamic loading']的一项任务(http://docwiki.embarcadero.com/RADStudio/XE3/en/Libraries_and_Packages#Dynamic_Loading_.28Windows-only.29)。 [+1] – TLama 2013-03-10 12:50:53
向我们展示您的'DLLPath'常量的真正定义。从[E2026错误描述](http://docwiki.embarcadero.com/RADStudio/XE3/en/E2026_Constant_expression_expected_(Delphi))中可以明显地看出我之所以要求这样做的原因。 – TLama 2013-03-10 12:07:11
什么是动态加载? btw:使用字符串作为参数没有sharemem将不是一个好主意。 – bummi 2013-03-10 12:07:34
@TLama - 我实际上已将DLLPath声明为字符串变量 – ple103 2013-03-10 12:11:09