delphixe3呼叫C語言開發的dll介面中引數之間資料型別轉換及處理

cms26發表於2018-07-17

寫這篇部落格的原因:之前我是用delphi7開發,在呼叫c版的dll介面時從沒有出現過問題,後來升級為delphixe3版本開發時,出現一些令人頭疼的問題,我費了很大勁才解決。

Delphixe3出現如下問題:

舉個例子:dll檔案介面定義如下

int testDLLfun(unsigned char*a,unsigned long aLen,  unsigned char* b, unsigned long * bLen);

當Delphi呼叫該函式時,若在delphi7中char*對應的是pchar型別(delphi7中預設的pchar就是PAnsichar型別),而從delphi2010版本以上pchar型別預設指的是PWidechar,因此在delphixe3中我們要定義成PAnsichar型別,在這裡我用的是靜態呼叫dll的方式。

function  testDLLfun(a:PAnsiChar;aLen:Integer; b:PAnsiChar;bLen:pInteger):Integer;stdcall;  external'dllName.dll' name  'testDLLfun';

具體實現呼叫delphi中的testDLLfun方法如下

function test(const  aStr: AnsiString): String;
var aStr1:AnsiString;
bLen,retcode:Integer;
b:PAnsiChar;
bMemoryStream:TMemoryStream;
aBytes:TBytes;
begin
bMemoryStream:=TMemoryStream.Create;
try
bLen:=2048;
SetLength(aBytes,1024);
aBytes:= DecodeBase64(aStr);//base64解碼
SetString(aStr1,PAnsiChar(aBytes),length(aBytes));//將解碼的位元組陣列轉成字串
GetMem(b,  bLen);    
retcode:=testDLLfun(PAnsiChar(aStr1),Length(aStr1),b,@bLen);
bMemoryStream.Write(b^,blen);//將dll介面中的輸出引數寫入流裡作為返回值輸出
bMemoryStream.Position:=0;
Result:= bMemoryStream.DataString;
finally
Finalize(aBytes);
FreeMem(b);
bMemoryStream.Free;
end;
end;

由於我實現的功能中必須要經過base64解碼後的引數傳入testDLLfun中,我試了多種的delphi中自帶的解碼方法,出現亂碼或字元長度不對的問題,導致呼叫testDLLfun失敗,經過測試,只有DecodeBase64方法是可以成功,先轉成位元組陣列,在轉成string,但具體的原因我也解釋不清,如果大家知道原因的,歡迎指教。

第一次發博,如有表達的不對或者想的不周到的,歡迎大家指出,我們一起進步。

相關文章