在 Delphi 中通过引用传递的指针(从 DLL 导入函数)
Pointers passed by reference in Delphi (import functions from DLL)
我想使用在 DLL 中声明的函数,该函数将指针作为 in/out 参数来填充具有非指针参数的记录。
来自 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;
记录:
MlaInfo = record
i : Integer;
idx : Integer;
name : TCharWFSBufferArray;
camPitchUm : double;
lensletPitchUm : double;
spotOffsetx : double;
spotOffsety : double;
lensletFocalLengthUm : double;
grdCorr0 : double;
grdCorr45 : double;
end;
函数调用:
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);
使用类似的函数将指针传递给整数它可以工作,在上面的例子中我有 Invalid Typecast 错误。
答案在 Parameters (Delphi) - Value and Variable Parameters 文档中。我加粗强调一下:
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.
关于你的情况,我的建议是声明一个新类型:
PMlaInfo = ^TMlaInfo;
并更改函数的签名:
function WFS_GetMlaData(AHandle: WFS_HDL; const AMlaInfo: PMlaInfo): Integer stdcall;
但是有一种“hack”(取消引用的指针):
PDouble((@MlaList[i].camPitchUm)^)
您的 DLL 函数声明不正确。原始 C 代码将所有这些参数作为指向双精度的指针 — double*
。万无一失、不会出错的解决方案是更改函数声明以匹配 C 代码。从所有函数参数中删除 var
修饰符。
另一种解决方案是再次更改函数声明,但这次是让它看起来更像惯用的 Delphi。保留 var
修饰符,但将参数的类型更改为 Double
而不是 PDouble
.
如果您进行第一个更改,那么您将通过将指针传递给记录成员来调用该函数:@MlaList[i].camPitchUm
没有类型转换。如果您改为进行第二个更改,那么您将通过直接传递记录成员来调用该函数,同样没有类型转换:MlaList[i].camPitchUm
.
我想使用在 DLL 中声明的函数,该函数将指针作为 in/out 参数来填充具有非指针参数的记录。
来自 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;
记录:
MlaInfo = record
i : Integer;
idx : Integer;
name : TCharWFSBufferArray;
camPitchUm : double;
lensletPitchUm : double;
spotOffsetx : double;
spotOffsety : double;
lensletFocalLengthUm : double;
grdCorr0 : double;
grdCorr45 : double;
end;
函数调用:
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);
使用类似的函数将指针传递给整数它可以工作,在上面的例子中我有 Invalid Typecast 错误。
答案在 Parameters (Delphi) - Value and Variable Parameters 文档中。我加粗强调一下:
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.
关于你的情况,我的建议是声明一个新类型:
PMlaInfo = ^TMlaInfo;
并更改函数的签名:
function WFS_GetMlaData(AHandle: WFS_HDL; const AMlaInfo: PMlaInfo): Integer stdcall;
但是有一种“hack”(取消引用的指针):
PDouble((@MlaList[i].camPitchUm)^)
您的 DLL 函数声明不正确。原始 C 代码将所有这些参数作为指向双精度的指针 — double*
。万无一失、不会出错的解决方案是更改函数声明以匹配 C 代码。从所有函数参数中删除 var
修饰符。
另一种解决方案是再次更改函数声明,但这次是让它看起来更像惯用的 Delphi。保留 var
修饰符,但将参数的类型更改为 Double
而不是 PDouble
.
如果您进行第一个更改,那么您将通过将指针传递给记录成员来调用该函数:@MlaList[i].camPitchUm
没有类型转换。如果您改为进行第二个更改,那么您将通过直接传递记录成员来调用该函数,同样没有类型转换:MlaList[i].camPitchUm
.