Reputation: 455
I want to use a function declared in a DLL which takes pointers as in/out parameters to fill up a record with non-pointer parameters.
Function from DLL:
function WFS_GetMlaData( handle: WFS_HDL;
mla_idx: Integer;
mla_name: TCharWFSBufferArray;
var cam_pitch_um: PDouble;
var lenslet_pitch_um: PDouble;
var center_spot_offset_x: PDouble;
var center_spot_offset_y: PDouble;
var lenslet_f_um: PDouble;
var grd_corr_0: PDouble;
var grd_corr_45: PDouble): Integer stdcall;
Record:
MlaInfo = record
i : Integer;
idx : Integer;
name : TCharWFSBufferArray;
camPitchUm : double;
lensletPitchUm : double;
spotOffsetx : double;
spotOffsety : double;
lensletFocalLengthUm : double;
grdCorr0 : double;
grdCorr45 : double;
end;
Function call:
if err = WFS_GetMlaData(handle,
MlaList[i].idx,
MlaList[i].name,
PDouble(MlaList[i].camPitchUm),
PDouble(MlaList[i].lensletPitchUm),
PDouble(MlaList[i].spotOffsetx),
PDouble(MlaList[i].spotOffsety),
PDouble(MlaList[i].lensletFocalLengthUm),
PDouble(MlaList[i].grdCorr0),
PDouble(MlaList[i].grdCorr45) ) then MyWFS_HandleErrors(handle, err);
With a similar function which passes pointers to integer it works, in the case above I have Invalid Typecast error.
Upvotes: 2
Views: 2068
Reputation: 163247
Your DLL function is declared incorrectly. The original C code has all those parameters as pointers to double — double*
. The sure-fire, can't-go-wrong solution is for you to change the function declaration to match the C code. Remove the var
modifiers from all the function parameters.
The alternative solution is again for you to change the function declaration, but this time to make it look a little more like idiomatic Delphi. Keep the var
modifiers, but change the parameters' type to Double
instead of PDouble
.
If you make the first change, then you would call the function by passing pointers to the record members: @MlaList[i].camPitchUm
with no type casting. If you make the second change instead, then you would call the function by passing the record members directly, again with no type casting: MlaList[i].camPitchUm
.
Upvotes: 4
Reputation: 4868
The answer is in the Parameters (Delphi) - Value and Variable Parameters documentation. My bold emphasizes it:
If a routine's declaration specifies a var parameter, you must pass an assignable expression - that is, a variable, typed constant (in the {$J+} state), dereferenced pointer, field, or indexed variable to the routine when you call it.
Regarding your case, my advice is to declare a new type:
PMlaInfo = ^TMlaInfo;
And change the signature of the function:
function WFS_GetMlaData(AHandle: WFS_HDL; const AMlaInfo: PMlaInfo): Integer stdcall;
But there's a sort of "hack" (dereferenced pointer):
PDouble((@MlaList[i].camPitchUm)^)
Upvotes: 2