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

C Delphi中通过引用传递的指针(从DLL导入函数),c,delphi,pointers,dll,delphi-xe7,C,Delphi,Pointers,Dll,Delphi Xe7,我想使用DLL中声明的函数,该函数将指针作为in/out参数,用非指针参数填充记录 来自DLL的函数: function WFS_GetMlaData( handle: WFS_HDL; mla_idx: Integer; mla_name: TCharWFSBufferArray; var cam_pitch_um: PDouble;

我想使用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);
使用一个类似的函数将指针传递给整数,它可以工作,在上面的例子中,我有一个无效的类型转换错误。

答案在文档中。我的报告强调:

如果例程的声明指定了一个var参数,则在调用例程时,必须向例程传递一个可赋值表达式,即变量、类型化常量(在{$J+}状态下)、取消引用的指针、字段或索引变量


关于您的情况,我的建议是声明一种新类型:

PMlaInfo = ^TMlaInfo;
并更改函数的签名:

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

但是有一种“黑客”(去引用指针):


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

另一种解决方案是再次更改函数声明,但这次要使它看起来更像惯用的Delphi。保留
var
修饰符,但将参数类型更改为
Double
,而不是
PDouble


如果您进行了第一次更改,则可以通过向记录成员传递指针来调用函数:
@MlaList[i].camPitchUm
,而不进行类型转换。如果您改为进行第二次更改,那么您可以通过直接传递记录成员来调用该函数,同样不进行类型转换:
MlaList[i].camPitchUm
PDouble((@MlaList[i].camPitchUm)^)
对我来说更好,因为我无法更改函数签名。是的,同时声明所有这些变量也会很无聊:-\Welcome to Stack Overflow。你标记了C++,但是这里没有C++的内容。也许您的意思是要包含这个DLL函数的C++(可能是真的C)声明。请将您的问题包括在内。您为什么要更改您接受的答案?您当前的选择建议一个无法实现的解决方案(因为不允许更改DLL函数),然后建议一个可疑的类型转换,该类型转换可能仅在禁用“typed@operator”选项时才编译(这是一个坏主意)。您以前选择的提供了两个您可以进行的更改,这两个更改将起作用,并为您提供更清晰的代码。如果我错了,请更正我,使用
var
,指针将为我提供指向指针的指针?
PDouble((@MlaList[i].camPitchUm)^)