C#調用動態庫出現“內存已損壞”提示


捕捉到的錯誤提示是這樣的:

System.AccessViolationException: 嘗試讀取或寫入受保護的內存。這通常指示其他內存已損壞

我用delphi嘗試去尋找造成這個錯誤的原因。先用delphi寫一個動態庫,方法如下:

 function Hello(Name:pchar):pchar; export;
 var
 myStr :string;
 begin
   myStr:='hi!' + string(Name);
   result:=pchar(myStr);
 end;

用C#調用

[DllImport("minmax.dll", CharSet = CharSet.Ansi)]
public static extern string Hello(string pName);

調用Hello("kevin")真的出現我期待的錯誤。於是在以為調整對字符的處理就能解決。

 function Hello1(Name:pchar):pchar; export;
 var
  Buffer:pchar;
  maxSize:integer;
 begin
   maxSize := sizeof(Name);
   GetMem(Buffer,maxSize);
  StrCopy(Buffer,Name);
   result:=Buffer;
 end;

其實兩個方法對於字符串的操作都沒有問題,問題是方法定義少了“stdcall”,調用第一行代碼

function Hello1(Name:pchar):pchar;stdcall; export;

兩個方法在C#調用都沒有問題了。到此我的問題想是找到方向了,但我意外發現一個有趣的現象,於是我想根究一下。因為我遇到問題的函數也是返回一個long。為了簡化描述,delphi里的方法是這樣,直接就返回-1

 function Hello2(pint:LongInt;row:integer;pname:pchar; pvalue:pchar):integer; stdcall; export;
 begin
   result:=-1;
 end;

C#里是這樣定義這個外部函數的

[DllImport("minmax.dll", CharSet = CharSet.Ansi)]
public static extern long Hello2(long pint, int row, string pname, string pvalue);

C#里調用Hello2會得到一個很大的數!並不是我所期待的-1!因為對delphi並不很熟悉,曾為了返回long用什么類型翻了書本,記得其longint其實是一個32的數字。於是將C#的定義語句的返回類型修改為int。結果-1如期的來了!這為我下面找到另一個內存損壞打好了基礎!

因為工作中需要調用的方法delphi是可以調用的,但C#調用就是了出錯,於是想通過delphi做一個動態庫作為中間包來使用,

FUNCTION put2 ( pint:LongInt; row:integer; pname:pchar; pvalue:pchar):integer; stdcall; export;
var
 bufferVal:pchar;
 maxSize:integer;
begin
   maxSize := sizeof(pvalue);
   GetMem(bufferVal,maxSize);
   StrCopy(bufferVal,pvalue);
   //調用目標庫的方法
   result:=-1;
end;

C#里這樣定義上面的外部函數

[DllImport("minmax.dll", CharSet = CharSet.Ansi)]
public static extern int put2(long pint, long row, string pname, string pvalue);

C#里調用put2也出現了內存損壞的提示。為什么呢?難道只因為put2比Hello1多了兩個long的參數?!腦袋突然閃過一個念頭,難道C++和delphi的long都32位,C#是64位,兩者對於long分配的內存大小不同!嘗試修改C#的外部函數定義

[DllImport("minmax.dll", CharSet = CharSet.Ansi)]
public static extern int put2(int pint, int row, string pname, string pvalue);

問題解決!

 

 

 

 

 

 

 

 

 


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com