最近一直被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代码如下:

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要小心!

困扰多日的C#调用Haskell问题竟然是Windows的一个坑的更多相关文章

  1. C#调用haskell遭遇Attempted to read or write protected memory

    1. Haskell的代码如下: 上面的代码中readMarkdown与writeHtmlString是pandoc中的函数,newString的作用是将String转换为IO CString. 2. ...

  2. 经过实际验证的C#调用Haskell的方法

    [系统环境] Windows Server 2008 R2,Haskell Platform 2013.2.0.0,ghc 7.6.3,cabal 1.16.0 [操作步骤] 1. 安装Windows ...

  3. paip.java c# .net php python调用c++ c dll so windows api 总结

    paip.java c# .net  php python调用c++ c dll so windows api 总结 作者Attilax  艾龙,  EMAIL:1466519819@qq.com 来 ...

  4. Notepad++中调用cl.exe编译器(Windows)

    Notepad++中调用cl.exe编译器(Windows) 近来在notepad++中写代码,写完后总是习惯性的想去VS里面编译一下,看看代码是否有误.但有时候一些零碎的小文件总是懒得再VS中打开, ...

  5. 我用C#调用C编译的dll中有这样一个函数,函数大概的功能就是把数据保存到buf缓冲区中:

    我用C#调用C编译的dll中有这样一个函数,函数大概的功能就是把数据保存到buf缓冲区中: C/C++ code   ? 1 int retrieve(int scanno,void* buf); 在 ...

  6. 关于php调用.net的web service 踩过的坑

    从前一阵开始,公司要和对方做web service对接.由于对方使用.net语言,而我方使用php.本来经理是要求我们也用.net写web service的服务端.而我上学时学的.net全忘了... ...

  7. 摄像头调用代码 笔记本的话,本身有一个摄像头,由于用的usb摄像头,需要把笔记本的摄像头禁用后,再使用

    摄像头调用代码 笔记本的话,本身有一个摄像头,由于用的usb摄像头,需要把笔记本的摄像头禁用后,再使用 <!DOCTYPE html> <html lang="en&quo ...

  8. 将前端js异步调用的多个服务合并为一个前端服务

    将前端js异步调用的多个服务合并为一个前端服务 1. 减少前端js异步请求的次数改善浏览体验 2. 方便地针对单个接口做异常降级处理

  9. 三界商城 ajax调用城市接口,竟然需要登录,调用的接口需要登录,如果不登录 重定向到登录

    现象 商家入驻 填写信息的 ajax请求没有数据 network->name-headers 返回302 发现调用的接口,需要登录,否则重定向登录 //初始化用户信息查询 public func ...

随机推荐

  1. mysql 重复数据防止插入:)

    insert into table (id, name, age) values(1, "A", 19) on duplicate key update name=values(n ...

  2. ubuntu 挂载windows共享目录的方法

    建立windows共享目录 右击要共享的文件夹-->属性-->高级共享-->添加用户-->添加完全控制权限 假设建立的共享地址为\\192.168.1.100\Linux 获取 ...

  3. 详解Oracle DELETE和TRUNCATE 的区别(摘)

    语法delete from aa truncate table aa 区别 1.delete from后面可以写条件,truncate不可以. 2.delete from记录是一条条删的,所删除的每行 ...

  4. python学习笔记2-functools.wraps 装饰器

    wraps其实没有实际的大用处, 就是用来解决装饰器导致的原函数名指向的函数 的属性发生变化的问题: 装饰器装饰过函数func, 此时func不是指向真正的func,而是指向装饰器中的装饰过的函数 i ...

  5. CSS基本知识和选择器

    一.CSS基本知识 内联式css样式,直接写在现有的HTML标签中 内联式css样式表就是把css代码直接写在现有的HTML标签中,如下面代码: <p style="color:red ...

  6. spilt()的用法

    split() 方法用于把一个字符串分割成字符串数组.<script type="text/javascript"> var str="How are you ...

  7. Sublime 保存时自动转换tab成空格

    笔者最近学习c, c语言的清新代码风格让人眼前一亮,不禁爱上这种写作风格,变量名.等号.常量值之间空格分隔,清爽便于阅读. 于是笔者以此为代码写作规范,查阅自己以前写的java代码,以下用notepa ...

  8. laravel 事件的使用案例

    以下是我对事件使用的一些记录 创建事件 执行以下命令,执行完成后,会在 app\Events 下面出现一个 DeleteEvent.php 文件,事件就在次定义 php artisan make:ev ...

  9. React Developer Tools 安装小提示

    1,在google市场里边,安装React Developer Tools之后,发现是开启的,但是按下F12后,并没有发现react选项 2,后来通过查资料,发现必须是运行react项目的时候,才出现 ...

  10. 菜鸟学自动化测试(八)----selenium 2.0环境搭建(基于maven)

    菜鸟学自动化测试(八)----selenium 2.0环境搭建(基于maven) 2012-02-04 13:11 by 虫师, 11419 阅读, 5 评论, 收藏, 编辑 之前我就讲过一种方试来搭 ...