2014-01-06 64 views
0

當前需要用Delphi編寫一個DLL,以便主程序調用指定位置在可移動磁盤中的一個文件中,Delphi使用函數設計返回一組數值整數記錄

主程序設計爲VC++,所以使用Strut的方式來調用DLL的數據輪!當主程序調用我的DLL,進入A組記錄等功能已被處理,返回B組記錄中遇到

目前存在的問題,

但用Delphi編寫的DLL,可以接收組記錄,但返回組B,但總是錯誤!

以下是該DLL函數的代碼,想問一下,如果有人遇到這樣的問題可以幫助提點充耳不聞

謝謝! !

enter code here 
library usbdll; 

uses 
Windows, 
SysUtils, 
Classes; 

{$R *.res} 

Type 
p_fin=^TSfin; 

TSfin = record //A group of Record is the main program calls incoming Record Type 
ST_act:Integer; 
pathlen:Integer;//Pass true path length, so that I can get to the far left pathlen, then to remove the rear garbled 
Id_hand:Integer; 
Id_tail:Integer; 

path: PWideChar://The reason why the file path Pwidechar do use guidelines because another branch dll is passed to the main program main program <file path + unicode>, is behind the path and dragging a bunch of gibberish characters 

Type 
p_out=^TRfout;//B Record is set to return to the main program of the Record Type 


TRfout= Record 
ST_act:Integer; 
ST_move:Integer; 
Revis:Integer; 
Crchk:Integer; 
end; 

//以下是我的評論。

//使用測試有兩種方式,直接返回到組B的Record,沒有收到組A的Record,一組沒有收到Record,當主程序調用時,立即返回相關數據,結果是正常的。

(* 

function RFoutEt(test:p_out):Boolean;stdcall; //ok Function writing mode 

begin 

test^.ST_act:=14; 
test^.ST_move:=10; 
test^.Revis:=12; 
test^.Crchk:=8;end;exports RFoutEt; 
procedure RFoutE(out Result:TRfout);cdecl; //ok Procedure writing mode 

begin 

Result.ST_act:=14; 
Result.ST_move:=10; 
Result.Revis:=12; 
Result.Crchk:=8;end;exports RFoutEt; 
*) 

//其實,我需要主程序記在我的A組記錄數據輸入爲了應對-OP後,得到真正想將文件移動到指定的真正道路,並最終返回到組B記錄。

function RFoutE(ap_sendin:p_fin;num:Integer):TRfout;stdcall; //error 

var 
str_tmp,str_tmp2,temi_diry:string; 
i,copyNum:Integer; 

arr: array[0..100] of Char; 

begin 

//Program by adding the following {} after paragraph, Result is not an empty value is displayed to access illegal address,causing abnormal program termination. 

{ 

StrCopy(arr,Pchar(ap_sendin^.path)); 
repeat 
str_tmp:=temi_diry;//Use the file path string char array A group referred to in the PWidechar removed 

str_tmp2:=arr[i]; 
Inc(i); 
until i>=ap_sendin.pathlen; 

copyNum:=Prs_Filecopy(temi_diry;ap_sendin^.path);//A group of Record with associated data to complete the move of the specified file 

} 

Result.ST_act:=4;//The following four lines of words alone are able to return data 
Result.ST_move:=0; 
Result.Revis:=2; 
Result.Crchk:=copyNum;end; 

PS。以下是使用VC++試用多種功能的測試正常需求

struct Sfin{ 

int ST_act;  
int pathlen; 
int Id_hand; 
int Id_tail; 
wchar_t *path; 
}; 

struct Rfout{ 

int ST_act; 
int ST_move; 
int Revis; 
int Crchk; 
}; 

Rfout RFoutE(struct Sfin *a, int num) 
{ 

int ret = 1; 
Rfout OutStruct; 


copyNum = Prs_Filecopy(temi_diry, inAnow, Anow->path); 
ret=1; 
if(ret==1){ 
    OutStruct.ST_act =14; 
    OutStruct.ST_move =10; 
    OutStruct.Revis = 12; 
    OutStruct.Crchk = 8; 
    Anow = freeA(Anow); 

} 
return OutStruct; 
} 

回答

1

對於大於機器字大小的返回值,沒有標準的ABI。而且Delphi使用了我遇到過的任何其他編譯器的不同ABI,所以你不會以這種方式返回大型記錄。

您需要將記錄作爲輸出參數而不是函數返回值返回。一旦你做出改變,一切都會好的。

它看起來像你的C++函數使用cdecl而不是stdcall。

+1

確實,返回記錄的方式差異很大。無論如何,Borland/Embarcadero編譯器都會返回大於32位的任何內容,即使該記錄已正式聲明爲函數結果。 MS在兩個寄存器EDX:EAX中返回高達64位,像Delphi這樣的大尺寸。其他編譯器也是這樣做的。區別在於可能作爲寄存器返回的記錄大小。 –