zoukankan      html  css  js  c++  java
  • 困扰多日的C#调用Haskell问题竟然是Windows的一个坑

    最近一直被C#调用Haskell时的“尝试读取或写入受保护的内存”问题所困扰(详见C#调用haskell遭遇Attempted to read or write protected memoryC#调用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调用pandoc的代码

    如果直接返回字符串,则一切正常,示例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上运行时,奇迹竟然出现了——运行正常,并且得到了正确的结果。

    markdown解析成功

    这时你也许又要问——不是自找麻烦吗,为什么不一开始就用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要小心!

  • 相关阅读:
    JVM中java类的加载时机(转载:http://blog.csdn.net/chenleixing/article/details/47099725)
    自定义filter包
    Tomcat中Listener的使用范例(转载http://cywhoyi.iteye.com/blog/2075848)
    Quartz简单使用
    PAT A1119 Pre- and Post-order Traversals [前序后序求中序]
    PAT A1115 Counting Nodes in a BST [二叉搜索树]
    PAT A1110 Complete Binary Tree [完全二叉树]
    PAT A1102 Invert a Binary Tree [反转二叉树]
    PAT A1099 Build A Binary Search Tree [二叉搜索树]
    PAT A1094 The Largest Generation [树的遍历]
  • 原文地址:https://www.cnblogs.com/dudu/p/csharp-haskell-windows.html
Copyright © 2011-2022 走看看