我目前正在编写一个模块,该模块与用于检查扫描仪的黑盒第 3 方 DLL 接口。我需要动态加载 DLL 函数,这适用于除一个函数之外的所有函数。
SetScanParameters 函数有一个记录结构作为参数,我认为它在某种程度上干扰了我用来动态加载它的方法(见下文)。动态加载时,函数会因访问冲突而中断。
但是,SetScanParameters 在静态加载时确实加载并正常运行。我还需要做些什么来动态加载具有记录结构的函数吗?
为清楚起见,自行编辑:
记录类型:
TBK_ScanParameter=packed record
Left:short;
Top:short;
Width:short;
Length:short;
//
xResolution:short;
yResolution:short;
BitsPerPixel:short;
LightControl:short;
MotorControl:short;
//
rGain:short;
gGain:short;
bGain:short;
rOffset:short;
gOffset:short;
bOffset:short;
rExposure:short;
gExposure:short;
bExposure:short;
//
FeedDirection:short;
CropImage:short;
ScanWithMICR:short;
//
Reserved:array [0..14] of short;
end;
静态声明:
function BK_SetScanParameter(var ScanParameter:TBK_ScanParameter):integer; cdecl;
静态实现:
function BK_SetScanParameter(var ScanParameter:TBK_ScanParameter):integer; cdecl; external 'BKV2.dll' name '_BK_SetScanParameter@4';
动态逻辑(或者如果我不必使用静态调用来使其工作,那将是什么动态逻辑):
function TdmScannerV2.SetScanParameter(pScanParameter: TBK_ScanParameter): string;
type
TBK_SetScanParameter = function (var ScanParameter:TBK_ScanParameter):integer; stdcall;
var
hV2Dll:HMODULE;
func:TBK_SetScanParameter;
begin
hV2Dll:=0;
result := '';
try
hV2Dll:=LoadLibrary('BKV2.dll');
if hV2Dll>0 then
begin
@func:=GetProcAddress(hV2Dll, '_BK_SetScanParameter@4');
if Assigned(@func) then
begin
try
if BK_SetScanParameter(pScanParameter) > 0 then {This one works, but is static}
//if func(pScanParameter) > 0 then {this one gets an AV}
begin
Result := 'Y:Scan Parameters Set';
end
else
Result := 'ERROR:Failure code returned';
{
if func(pScanParameter) > 0 then
Result := 'Y:Scan Parameters Set'
else
Result := 'ERROR:Failure code returned';
}
except
on e:Exception do
begin
Result := 'ERROR:Exception:' + e.Message;
end;
end;
end
else
Result := 'ERROR:Unable to load BK_SetScanParameter';
end
else
Result := 'ERROR:Unable to load BKV2.dll';
finally
if hV2Dll>0 then FreeLibrary(hV2Dll);
end;
end;
我已经尝试在动态上使用 stdcall、cdecl、safecall、pascal 和 register,它们都导致了 AV。我还尝试在结构 [1..15] 而不是 [0..14] 中创建数组。但我没有得到的是,如果我将结构传递给静态版本,它就可以工作。
此外,OP中有一些错别字,对此我深表歉意。我正在重写 OP 中的代码并做了一些拼写错误,这可能会使线程有点混乱。我已经用当前测试功能的复制/粘贴替换了它。
编辑:下面是 DLL 文档中描述的 typedef:
typedef struct ScanParameter
{
short Left; // left start positsion
short Top; // top start positsion
short Width; // scan image width in 1/100 inch
short Length; // scan image length in 1/100 inch
short xResolution; // horizontal resolution
short yResolution; // vertical resolution
short BitsPerPixel; // 24bit color, 8bit gray
short LightControl; // 0 - All lamp Off, 1 - red, 2 - green, 3 - blue, 4 - All lamp On
short MotorControl; // Motor Control, 0 - off, 1 = on
short rGain; // AFE R-Gain
short gGain; // AFE G-Gain
short bGain; // AFE B-Gain
short rOffset; // AFE R-Offset
short gOffset; // AFE G-Offset
short bOffset; // AFE B-Offset
short rExposure; // AFE R-Exposure
short gExposure; // AFE G-Exposure
short bExposure; // AFE B-Exposure
short FeedDirection; // feedout paper direction, 0 –fordward, 1 - backward
short CropImage; // 0 - no trim edge , 1 - trim edge
short ScanWithMICR; // 0 –off, 1 –scan image until paper leave device
short Reserved[15];
} ScanParameter;