I am currently writing a module which interfaces with a black box 3rd party DLL for a check scanner. I need to have the DLL functions loaded dynamically, and this is working for all but one function.
The SetScanParameters function has a record structure as a parameter, which I believe is somehow interfering with the methodology I am using to dynamically load it (see below). When loaded dynamically, the function is interrupted by an access violation.
SetScanParameters does load and function properly when statically loaded, however.
Is there something else that I need to be doing to dynamically load a function with a record structure?
self-edited for clarity:
Record type:
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;
Static declaration:
function BK_SetScanParameter(var ScanParameter:TBK_ScanParameter):integer; cdecl;
Static implementation:
function BK_SetScanParameter(var ScanParameter:TBK_ScanParameter):integer; cdecl; external 'BKV2.dll' name '_BK_SetScanParameter@4';
Dynamic logic (or what would be dynamic logic if I didn't have to use the static call to make it work):
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;
And I've tried using stdcall, cdecl, safecall, pascal, and register on the dynamic and they all resulted in the AV. I also tried making the array in the struct [1..15] instead of [0..14]. And in the But what I don't get is, if I pass the struct into the static version, it works.
Also, there were a few typos in the OP, and I apologize for that. I was re-writing the code in the OP and made a few typos, which may've muddied the thread a bit. I've replaced it with a copy/paste of the current test function.
edit: Below is the typedef as described by the documentation for the DLL:
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;