2016-02-16 88 views
2

我想使用在DLL中聲明的函數,該函數以指針作爲in/out參數來填充非指針參數的記錄。從DLL在Delphi中通過引用傳遞的指針(從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); 

隨着其穿過指針整數它的工作原理類似的功能,在上述的情況下我有無效的類型轉換錯誤。

+0

歡迎來到Stack Overflow。你標記了這個C++,但這裏沒有關於C++的東西。也許你打算包含這個DLL函數的C++(可能是真正的C)聲明。請[編輯]你的問題,包括這一點。 –

+0

你爲什麼改變你接受的答案?你當前的選擇建議你不能實現的解決方案(因爲你不允許改變DLL函數),然後建議一個可疑的類型轉換,可能只有在你禁用「typed @ operator」選項時纔會編譯(這是一個壞主意)。你之前的選擇提供了兩個你可以做的改變,它可以工作並給你更清晰的代碼。 –

回答

2

答案在Parameters (Delphi) - Value and Variable Parameters文檔中。我大膽強調它:

如果一個例程的聲明指定一個變量參數,你必須通過分配的表達 - 也就是一個變量,類型常量(在{$ J +}狀態),復引用指針,字段或索引變量在您調用時發送到例程。


關於你的情況,我的建議是宣告一個新的類型:

PMlaInfo = ^TMlaInfo; 

並且把函數的簽名:

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

但是,有一個排序「hack」(dereferenc ed指針):

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

'PDouble((@ MlaList [i] .camPitchUm)^)'起作用,對我來說更好,因爲我無法更改函數簽名。 – meller92

+1

是的,也聲明所有這些變量將無聊: - \ – fantaghirocco

4

您的DLL函數聲明不正確。原始C代碼將所有這些參數指向雙倍的指針 - double*。確定的,不可能出錯的解決方案是讓你改變函數聲明以匹配C代碼。從所有函數參數中刪除var修飾符。

另一種解決方案是再次爲您更改函數聲明,但這次使它看起來更像慣用的Delphi。保留var修飾符,但將參數的類型更改爲Double而不是PDouble

如果您進行了第一次更改,那麼您可以通過將指針傳遞給記錄成員來調用該函數:@MlaList[i].camPitchUm,不進行類型轉換。如果你做第二次改變,那麼你可以通過直接傳遞記錄成員來調用該函數,而不用進行類型轉換:MlaList[i].camPitchUm

+0

糾正我如果我錯了,使用'var'和指針給我指針指針? – meller92

+0

這通常是正確的,梅勒。 –