Delphi Http Https 最好的解决方法(三) LoadLibrary扩展

文章描述了一位开发者在DelphiXE10.1柏林环境下遇到的DLL集成问题,具体是DLL依赖的libeay32.dll和ssleay32.dll无法正确加载。作者尝试了三种解决方案,包括在主程序中导入DLL、在DLL工程文件中指定路径以及在DLL内部获取自身路径加载依赖库,最后推荐了第三种方法作为最佳实践。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

开发环境: Delphi XE 10.1 Berlin

前提文章: Delphi Http Https 最好的解决方法(二)

目录

1. 项目描述

2. 问题描述

3. 解决方案

        3.1 主程序在导入dll方法单元处理(不推荐)

        3.2 在dll的工程文件处加入(不推荐)

        3.3 在dll的工程文件获取dll(HelpTool.dll)的当前路径(推荐方案)

4. 结语


1. 项目描述

        之前我关于http、https封装的dll(我用XE10.1编译,依赖10.1的libeay32.dll 和 ssleay32.dll)是运用于一个独立的exe程序,是没有问题的。可最近做一个银行转账的接口,需要在主程序的基础上进行集成,我查看主程序的应用目录已经存在 libeay32.dll 和 ssleay32.dll ,主程序是一个很庞大的HIS项目,我就担心集成(替换原相关dll)后会影响原系统相关功能。

2. 问题描述

        我编译了一个Demo程序模拟主程序,导入HelpTool.dll方法,其中我定义如下:

const
  dllName= '银企接口\app\HelpTool.dll';

        以及在该目录下创建【银企接口\app】目录,如下:

        

        银企接口目录下有一个app的文件夹,如下:

        

        我运行Demo程序“D6Demo.exe” 发起https请求,提示 Could not load SSL library

        我看libeay32.dll和ssleay32.dll是和HelpTool.dll同目录,怎么会提示这个错误。

        我猜测应该是路径的问题,然后我查看日志信息,发现HekpTool.dll里的日志

        竟然写在了exe目录的log目录下(应该是和dll同目录),初步确定是路径问题。

        原本我这样把exe和dll分离不同目录,也从没有搞过,就只有百度查找了。

        方案没找到,倒是找到了一个关键词"LoadLibrary", 赶紧试试看!

3. 解决方案

        3.1 主程序在导入dll方法单元处理(不推荐)

        在Demo程序dll导入接口添加如下代码,指定载入libeay32.dll 和 ssleay32.dll:

initialization
  LoadLibrary(Pchar('银企接口\app\libeay32.dll'));
  LoadLibrary(Pchar('银企接口\app\ssleay32.dll'));
finalization
  //

        使用Demo发起https请求成功. 这样将dll路径写死,不推荐这样操作.

        3.2 在dll的工程文件处加入(不推荐)

        在dll里指定载入libeay32.dll 和 ssleay32.dll

begin
  LoadLibrary(Pchar(TFilePath.AppPath+ '银企接口\app\libeay32.dll'));
  LoadLibrary(Pchar(TFilePath.AppPath+ '银企接口\app\ssleay32.dll'));
end.

        使用Demo发起https请求成功. 这样将dll路径写死,不推荐这样操作.

        3.3 在dll的工程文件获取dll(HelpTool.dll)的当前路径(推荐方案)

        之前在Demo的dll导入单元,已指定了HelpTool.dll的路径。那么在HelpTool.dll里,直接获取dll自身的路径,来导入libeay32.dll和ssleay32.dll。

        dll获取自身路径方法:

Function GetDllDir:string;
var
  ModuleName:string;
  I, iCnt: Integer;
  dllDir: string;
begin
  dllDir:= '';
  SetLength(ModuleName, 255);
  //取得Dll自身路径的目录
  GetModuleFileName(HInstance, PChar(ModuleName), Length(ModuleName));
  iCnt:= DataFJ(ModuleName, '\'); //最后一个就是文件名"HttpTool.dll"
  for I := 1 to iCnt- 1 do
  begin
    if dllDir<>'' then dllDir:= dllDir+ '\';
    dllDir:= dllDir+ arr_dir[I];
  end;
  Result := dllDir;
end;
function DataFJ(Cin: string; CS: string = '|'): Integer;
var
  i, j, jl1: integer;
begin
  Result := 1;
  jl1 := 1;
  j := 1;
  for i := Low(arr_dir) to High(arr_dir) do
    arr_dir[i] := '';
  for i := 1 to (length(Cin)) do
  begin
    if Cin[i] = CS then
    begin
      arr_dir[j] := copy(Cin, jl1, i - jl1);
      jl1 := i + 1;
      j := j + 1;
    end;
  end;
  arr_dir[j] := copy(Cin, jl1, i + 1 - jl1);
  Result := j;
end;

        在dll的工程文件加入如下代码:

var
  dllPath: string;

begin
  dllPath:= GetDllDir;
  LoadLibrary(Pchar(GetDllDir+ '\libeay32.dll'));
  LoadLibrary(Pchar(GetDllDir+ '\ssleay32.dll'));
end.

         使用Demo发起https请求成功!!!

4. 结语

        综合以上三种方案,结合自身项目开发方案,我选择第三种,当然,那种方便用哪种。

       

        

### Delphi 中 `LoadLibrary` 函数的功能与作用 `LoadLibrary` 是 Windows API 提供的一个重要函数,在 Delphi 编程中被广泛用于动态加载 DLL 文件。该函数的主要功能是从磁盘加载指定的动态链接库(Dynamic Link Library,简称 DLL),并返回一个句柄以便后续操作。 #### 功能描述 `LoadLibrary` 的核心功能是将指定路径下的 DLL 加载到内存中,并返回一个模块句柄(HMODULE)。通过这个句柄可以进一步获取 DLL 中导出的函数地址或其他资源[^1]。如果成功加载,则返回有效的 HMODULE 值;否则返回 NULL 并设置错误码。 #### 参数说明 此函数接受单个参数——指向包含要加载的 DLL 名称字符串指针。例如: ```delphi function LoadLibrary(lpLibFileName: PChar): THandle; ``` 其中 `lpLibFileName` 表示目标 DLL 文件名或者完整路径[^2]。 #### 使用场景分析 以下是几种常见的使用场景: 1. **延迟绑定** 当应用程序启动时不需要立即初始化某些特性或组件时,可以通过 `LoadLibrary` 实现按需加载特定功能所需的外部依赖项。 2. **跨平台兼容性处理** 针对不同操作系统架构 (Win32 vs Win64),开发者可以根据实际情况有条件地调用相应版本的 DLL 来适配硬件环境差异[^3]: ```delphi {$IFDEF WIN32} hDLL := LoadLibrary('mylibrary32.dll'); {$ELSE} hDLL := LoadLibrary('mylibrary64.dll'); {$ENDIF} ``` 3. **增强安全性控制** 应用程序可以在运行期间验证签名后的可信第方插件是否存在篡改行为后再决定是否允许执行它们内部逻辑。 4. **扩展应用能力** 利用自定义编写的辅助工具包形式分发额外业务流程实现细节而不修改主程序源代码结构本身即可轻松集成新特性支持。 #### 示例代码展示如何正确运用 `GetProcAddress()` 结合 `LoadLibrary()` 假设我们有一个名为 `example.dll` 的动态库文件,它暴露了一个简单的加法运算接口 `AddNumbers(int a, int b)` ,我们可以这样来访问它的服务: ```delphi type TAddFunction = function(a, b: Integer): Integer; stdcall; var LibHandle: THandle; AddFunc: TAddFunction; begin // 尝试打开 example.dll LibHandle := LoadLibrary('example.dll'); if LibHandle <> 0 then try @AddFunc := GetProcAddress(LibHandle, 'AddNumbers'); if Assigned(AddFunc) then Writeln('Result of adding numbers:', AddFunc(5, 7)) else Writeln('Failed to locate procedure.'); finally FreeLibrary(LibHandle); end else Writeln('Could not load the library.'); end. ``` 以上片段展示了完整的生命周期管理过程:从装载共享对象直至释放关联资源为止。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值