記:
近期在C#中調用別人的DLL的時候有時候出現了 嘗試讀取或寫入受保護的內存 。這通常指示其他內存已損壞 的問題。
錯誤類型:System.AccessViolationException。
問題位置:在與C++ dll規定傳參的類型用的是string導致
問題原因:C++ string類的字符在內存的儲存位置:數據<=16字節,在當前棧區;數據>16字節,在堆區
C# string是存放在堆區的。
解決方案:在傳值的時候用指針,再做轉換就好了。
public class APP_DLL { [DllImport("ruihua.dll", CallingConvention = CallingConvention.Cdecl)] //引入dll,並設置字符集 public static extern int test(byte[] src1, int w1, int h1, int channel1, byte[] src2, int w2, int h2, int channel2, string str); }
改為:
public class APP_DLL { [DllImport("ruihua.dll", CallingConvention = CallingConvention.Cdecl)] //引入dll,並設置字符集 public static extern int test(byte[] src1, int w1, int h1, int channel1, byte[] src2, int w2, int h2, int channel2, IntPtr str); }
C# string轉IntPtr方法:
IntPtr ptrIn = Marshal.StringToHGlobalAnsi(obj.ToString());
C# IntPtr轉string方法:
string retlust = Marshal.PtrToStringAnsi(ptrIn);