开发环境: 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. 结语
综合以上三种方案,结合自身项目开发方案,我选择第三种,当然,那种方便用哪种。