Yönetilmeyen DLL içe aktarmalarını C# ye dönüştürmeyi öğrendim ... Ve tam olarak anlamadığım bir şeyle karşılaşıyorum.Delphi DLL dönüş dizesi C# ... .NET 4.5 Yığın Bozulması ancak .NET 4.0 çalışır? Açıkla lütfen?
Delphi, Benim anlayış bir Procedure SomeFunc() : PChar; Stdcall;
den Result := NewStr(PChar(somestring))
dönen bir fonksiyon vardır, newstr sadece yerel yığın bir tampon ayırır ... ve SomeFunc kendisine bir işaretçi geri dönüyor. .NET 4.0 (Müşteri Profili) olarak
[DllImport("SomeDelphi.dll", EntryPoint = "SomeFunc", CallingConvention = CallingConvention.StdCall)]
public static extern String SomeFunc(uint ObjID);
Bu işleri (veya David söylediği gibi, "çalışmak için görünür") Windows 7 .NET 4.0 İstemci Profili cezası. Windows 8'de, bu yolu beni aşağıya getiren tahmin edilemez bir davranışı var.
Yani aynı kodu .NET 4.5'te denemeye karar verdim ve Yığın bozulmasıyla ilgili hatalar oluştu. Tamam, şimdi biliyorum ki bu işlerin yapılması için doğru bir yol değil. Bu yüzden daha fazla kazmak:
Hala[DllImport("SomeDelphi.dll", EntryPoint = "SomeFunc", CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr _SomeFunc();
public static String SomeFunc()
{
IntPtr pstr = _SomeFunc();
return Marshal.PtrToStringAnsi(pstr);
}
Bu sorunsuz olarak çalışmasını .NET 4.5. Benim (acemi) kaygım, NewStr() 'in bu belleği tahsis etmesi ve sonsuza kadar orada oturması. Endişem geçerli değil mi?
.NET 4.0, ben bile bunu yapabilirsiniz ve özel bir durum oluşturmaz:
[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;
}
Bu kod 4,5 aynı yığın istisna atar ancak. Bu, problemin, .Net 4.5'de, marşetin FreeCoTaskMem() için çalıştığını ve istisnaları fırlattığı gerçeğinde olduğuna inanmamı sağlıyor.
Yani sorular:
Neden bu .Net 4.0 iş değil 4.5 yapar?
NewStr() 'ın yerel DLL dosyasında tahsisi konusunda endişelenmeli miyim?
# 2'ye "Hayır" cevabını verirseniz, ikinci kod örneği geçerlidir?
Kayıt için, aynı makine, aynı işletim sistemi, aynı derleyici, aynı şey. Sadece sağ tıklayın Proje -> çerçeve 4.5 ve viyola değiştirin, çöker. Her neyse, doğru anladığıma sevindim ve yardımın için her zaman olduğu gibi teşekkürler. –