在Delphi中通过引用传递的指针(从DLL导入函数)

时间:2016-02-16 11:02:45

标签: c delphi pointers dll delphi-xe7

我想使用DLL中声明的函数,该函数将指针作为输入/输出参数来填充带有非指针参数的记录。

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 错误。

2 个答案:

答案 0 :(得分:4)

您的DLL函数声明不正确。原始C代码将所有这些参数作为指针加倍 - double*。肯定的,可以解决的错误解决方案是让您更改函数声明以匹配C代码。从所有函数参数中删除var修饰符。

另一种解决方案是再次为您更改函数声明,但这一次使它看起来更像是惯用的Delphi。保留var修饰符,但更改参数'输入Double代替PDouble

如果您进行了第一次更改,那么您可以通过将指针传递给记录成员来调用该函数:@MlaList[i].camPitchUm而不进行类型转换。如果您进行第二次更改,那么您将通过直接传递记录成员来调用该函数,而不再使用类型转换:MlaList[i].camPitchUm

答案 1 :(得分:2)

答案在Parameters (Delphi) - Value and Variable Parameters文档中。我的大胆强调它:

  

如果例程的声明指定了var参数,则必须传递一个可赋值的表达式 - 即一个变量,类型常量(在{$ J +}状态下),解释指针,字段或索引变量到例程。

关于你的情况,我的建议是申报一个新类型:

PMlaInfo = ^TMlaInfo;

并更改功能的签名:

function WFS_GetMlaData(AHandle: WFS_HDL; const AMlaInfo: PMlaInfo): Integer stdcall;

但是有一种" hack " (解除引用指针):

PDouble((@MlaList[i].camPitchUm)^)