Tôi đã được học về marshaling nhập DLL không quản lý vào C# ... Và tôi đã đi qua một cái gì đó tôi không hoàn toàn hiểu.Chuỗi Delphi DLL trả về từ C# ... .NET 4.5 Heap Corruption nhưng .NET 4.0 hoạt động? Vui lòng giải thích?
Trong Delphi, có một chức năng mà đang trở lại Result := NewStr(PChar(somestring))
từ một Procedure SomeFunc() : PChar; Stdcall;
Từ hiểu biết của tôi, newstr chỉ phân bổ một bộ đệm trên heap địa phương ... và SomeFunc đang trở lại một con trỏ đến nó.
Trong .NET 4.0 (Client Profile), qua C# Tôi có thể sử dụng:
[DllImport("SomeDelphi.dll", EntryPoint = "SomeFunc", CallingConvention = CallingConvention.StdCall)]
public static extern String SomeFunc(uint ObjID);
này hoạt động (hoặc như David nói, "xuất hiện để làm việc") tốt trong Windows 7 .NET 4.0 Client Profile. Trong Windows 8, nó có hành vi không thể đoán trước, điều đó đã khiến tôi rơi xuống con đường này.
Vì vậy, tôi đã quyết định thử cùng một mã trong .NET 4.5 và có lỗi tham nhũng Heap. Được rồi, vì vậy bây giờ tôi biết đây không phải là cách chính xác để làm việc. Vì vậy, tôi đào thêm:
Vẫn trong .NET 4,5
[DllImport("SomeDelphi.dll", EntryPoint = "SomeFunc", CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr _SomeFunc();
public static String SomeFunc()
{
IntPtr pstr = _SomeFunc();
return Marshal.PtrToStringAnsi(pstr);
}
này hoạt động mà không có một xô. Mối quan tâm của tôi (người mới) là NewStr() đã phân bổ bộ nhớ này và nó chỉ ngồi đó mãi mãi. Mối quan tâm của tôi không hợp lệ?
Trong .NET 4.0, tôi thậm chí có thể làm điều này và nó không bao giờ ném một ngoại lệ:
[DllImport("SomeDelphi.dll", EntryPoint = "SomeFunc", CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr _SomeFunc();
public static String SomeFunc()
{
String str;
IntPtr pstr = _SomeFunc();
str = Marshal.PtrToStringAnsi(pstr);
Marshal.FreeCoTaskMem(pstr);
return str;
}
Mã này ném ngoại lệ đống cùng trong 4.5, tuy nhiên. Điều này khiến tôi tin rằng vấn đề nằm trong thực tế là trong .Net 4.5, marshaler đang cố gắng để FreeCoTaskMem() và đó là những gì đang ném các ngoại lệ.
Vì vậy, câu hỏi:
Tại sao công việc này trong Net 4.0 và không 4.5?
Tôi có nên lo lắng về việc phân bổ NewStr() trong DLL gốc không?
Nếu trả lời "Không" cho # 2, thì ví dụ mã thứ hai là hợp lệ?
Đối với hồ sơ, nó là cùng một máy, cùng một hệ điều hành, cùng một trình biên dịch, cùng tất cả mọi thứ. Chỉ cần kích chuột phải vào Project -> thay đổi framework thành 4.5 và viola, nó bị treo. Dù sao, tôi vui vì tôi đã hiểu nó một cách chính xác, và cảm ơn như luôn luôn cho sự giúp đỡ của bạn. –