程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> 關於C# >> C#調用Haskell時的“嘗試讀取或寫入受保護的內存”問題

C#調用Haskell時的“嘗試讀取或寫入受保護的內存”問題

編輯:關於C#

最近一直被C#調用Haskell時的“嘗試讀取或寫入受保護的內存”問題所困擾(詳見C#調用haskell遭遇Attempted to read or write protected memory,C#調用haskell時的“嘗試讀取或寫入受保護的內存”問題),而且困在其中,越陷超深,無法自拔,差點棄用C#解決我們面臨的問題。

問題是這樣的,只要在Haskell代碼中對字符串進行操作,在C#調用時就會引發異常:

An unhandled exception of type 'System.AccessViolationException' occurred in Unknown Module.

Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

示例Haskell代碼如下:

如果直接返回字符串,則一切正常,示例Haskell代碼如下:

C#調用示例代碼:

class Native
{
    [DllImport("libpandoc", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
    public static extern IntPtr markdownToHtml(byte[] markdown);
}
   
public class Processor 
{
    public string Process(string text)
    {
        var intPtr = Native.markdownToHtml(System.Text.Encoding.UTF8.GetBytes(text));
        var html =  Marshal.PtrToStringAnsi(intPtr);
        return html;
    } 
}

你也許會問——吃飽撐著了,為什麼要用C#調用Haskell?

沒撐著!因為史上最強大的Markdown引擎pandoc就是用Haskell開發的,不是C#,不是Java,不是PHP,不是Python,也不是C/C++,更不是Objective-C。真正要比的不是語言,而且是用語言開發出來的東西。

你也許要問——很多人看不起的微軟家的C#能調用高上大的Haskell?

當然能!而且經過了實際驗證,詳見經過實際驗證的C#調用Haskell的方法。雖然是通過FFI(ForeignFunctionInterface),借助C編譯成非托管的dll,但不管怎麼樣,C#做到了。

但當我們用C#調用Haskell解決實際問題時,遭遇了“Attempted to read or write protected memory. ”問題,反復折騰找不到解決之道,處於絕望中,以為“C#可以調用Hakell"是一個“騙局”。

。。。

今天上午,當我們把編譯好的程序從Windows Server 2008 R2復制到Windows Server 2012上運行時,奇跡竟然出現了——運行正常,並且得到了正確的結果。

這時你也許又要問——不是自找麻煩嗎,為什麼不一開始就用Windows Server 2012?

不是自找麻煩,是麻煩自己找上門的。因為編譯Haskell代碼需要安裝Haskell Platform(集成了ghc),而Haskell Platform不能在Windows Server 2012正常安裝,只能被迫在Windows Server 2008上安裝(當時也被折騰了)。

萬萬沒有想到的是,Windows Server 2008上編譯出來的程序不能在Windows Server 2008上正常運行,卻奇跡般地能在Windows Server 2012上能正常運行。這是不是Windows的一個坑呢?

由此想到我們在阿裡雲上曾經遭遇的“黑色10秒”問題,是因為Windows Server 2008在WAS(Windows Process Activation Service)中使用了spinlock,而虛擬化技術對spinlock支持不好,最終也是通過換用Windows Server 2012解決了問題。這雖然不能說是Windows Server 2008的一個坑,但說明了一點——使用Windows Server,2008要小心!

查看本欄目

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved