【系统环境】

Windows Server 2008 R2,Haskell Platform 2013.2.0.0,ghc 7.6.3,cabal 1.16.0

【操作步骤】

1. 安装Windows版Haskell Platform(不支持Windows Server 2012),Haskell Platform集成了cabal(相当于.NET中的msbuild+nuget), ghc(Glasgow Haskell Compiler,Haskell编译器)

2. 编写Haskell代码保存于.hs文件中,代码中加上foreign export ccall,示例代码如下:

3. 编写C代码保存于.c文件中,代码如下:

#include <windows.h>
#include <Rts.h> extern void __stginit_LibPandoc(void); BOOL STDCALL DllMain(HANDLE hModule, DWORD reason, void* reserved)
{
static char* args[] = {"libpandoc", NULL};
if (reason == DLL_PROCESS_ATTACH) {
startupHaskell(, args, __stginit_LibPandoc);
}
return TRUE;
}

4. 编写cabal配置文件保存于.cabal文件中,比如:

Name:                   libpandoc
Version: 0.5
Cabal-Version: >= 1.2
Build-Type: Simple
Executable libpandoc.dll
If os(windows)
CPP-Options: -DWIN32
Extensions: ForeignFunctionInterface
Hs-Source-Dirs: src
Include-Dirs: src
C-Sources: src/pandoc.c
Install-Includes: pandoc.h
Main-Is: LibPandoc.hs
Ghc-Options: -no-hs-main -optl-shared -optl-s

5. 在Haskell项目所在的文件夹运行命令cabal build进行编译,编译成功后会生成头文件,比如build\libpandoc.dll\libpandoc.dll-tmp\LibPandoc_stub.h

#include "HsFFI.h"
#ifdef __cplusplus
extern "C" {
#endif
extern HsPtr markdownToHtml(HsPtr a1);
#ifdef __cplusplus
}
#endif

6. 创建用于调用Haskell的C#项目

7. 将编译出来的dll文件(比如libpandoc.dll)复制到C#项目的bin文件夹中

8. 在C#中通过DllImport引用Haskell编译出来的dll文件

class Native
{
[DllImport("libpandoc", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
public static extern IntPtr markdownToHtml(byte[] markdown);
}

9. 在C#中调用Haskell通过foreign export ccall暴露出来的函数,示例代码如下:

public class Processor
{
public string Process(string text)
{
var intPtr = Native.markdownToHtml(Encoding.UTF8.GetBytes(text));
var html = Marshal.PtrToStringAnsi(intPtr);
return html;
}
}

【参考资料】

Calling Haskell from C#

Call a Haskell function in .NET

libpandoc源代码

libpandoc-dotnet源代码

经过实际验证的C#调用Haskell的方法的更多相关文章

  1. 困扰多日的C#调用Haskell问题竟然是Windows的一个坑

    最近一直被C#调用Haskell时的“尝试读取或写入受保护的内存”问题所困扰(详见C#调用haskell遭遇Attempted to read or write protected memory,C# ...

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

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

  3. js调用php和php调用js的方法举例

    js调用php和php调用js的方法举例1 JS方式调用PHP文件并取得php中的值 举一个简单的例子来说明: 如在页面a.html中用下面这句调用: <script type="te ...

  4. Jquery Ajax调用aspx页面方法

    Jquery Ajax调用aspx页面方法 在asp.net webform开发中,用jQuery ajax传值一般有几种玩法 1)普通玩法:通过一般处理程序ashx进行处理: 2)高级玩法:通过as ...

  5. zabbix调用api检索方法

    环境 zabbix:172.16.128.16:zabbix_web:172.16.16.16/zabbix 用户名:Admin 密码:zabbix 获取的数据仅做参考,以Linux发送HTTP的PO ...

  6. ASP.Net:Javascript 通过PageMethods 调用后端WebMethod方法 + 多线程数据处理 示例

    ASP.Net:Javascript 通过PageMethods 调用后端WebMethod方法 + 多线程数据处理 示例 2012年04月27日 16:59:16 奋斗的小壁虎 阅读数:4500   ...

  7. SNF快速开发平台MVC-EasyUI3.9之-WebApi和MVC-controller层接收的json字符串的取值方法和调用后台服务方法

    最近项目组很多人问我,从前台页面传到后台controller控制层或者WebApi 时如何取值和运算操作. 今天就都大家一个在框架内一个取值技巧 前台JS调用代码: 1.下面是选中一行数据后右键点击时 ...

  8. Struts2 调用非execute方法

    调用非execute方法 1)如果你的Action类是继承自ActionSupport的话,确切的说是重写了execute方法,ActionSupport里的默认实现就是返回"success ...

  9. Python开发基础-Day20继承实现原理、子类调用父类的方法、封装

    继承实现原理 python中的类可以同时继承多个父类,继承的顺序有两种:深度优先和广度优先. 一般来讲,经典类在多继承的情况下会按照深度优先的方式查找,新式类会按照广度优先的方式查找 示例解析: 没有 ...

随机推荐

  1. python 正则表达式 group() groups()

    参考地址: http://www.cnblogs.com/kaituorensheng/archive/2012/08/20/2648209.html

  2. maven下载的jar相应pom文件下载不完整问题。

    今天遇到一个奇葩问题: 同样的项目,我启动报错 : 某个class文件找不到.. 查找maven 依赖也的确没有找到 对应的jar 包. 查找同事项目,可以看到该class对应的 jar 包 是 lo ...

  3. centos下安装nodejs

    1.首先要安装gcc, # yum install libtool automake autoconf gcc-c++ openssl-devel 2.可以进入某个目录,下载NodeJS v0.10. ...

  4. On the internet, nobody known you are a dog !

  5. 【Linux】ODBC安装

    ODBC介绍 ODBC是Open Database Connect 即开发数据库互连的简称,它是一个用于访问数据库的统一界面标准.ODBC引入一个公共接口以解决不同数据库潜在的不一致性,从而很好的保证 ...

  6. sticky footer 布局

    <!doctype html><html lang="en"> <head> <meta charset="UTF-8" ...

  7. php->是什么意思

    在php中经常会看到这种符号,但是不明白是什么意思,有没有细心点的朋友帮讲讲,请不要说看手册之类的话.如果真给我讲明白了,我还会有加分的哦!比如这个中的符号是什么意思:$sql=$mydami-> ...

  8. 2019.02.06 bzoj2987: Earthquake(类欧几里得)

    传送门 题意简述:求满足ax+by+c≤0ax+by+c\le0ax+by+c≤0的二元组(x,y)(x,y)(x,y)对数. 思路: 类欧几里得算法模板题. 把式子变化一下变成:求满足0≤y≤−ax ...

  9. Mybatis-Plus 实战完整学习笔记(三)------导入MybatisPlus环境

    1.dao层接口引入 package com.baidu.www.mplus.mapper; import com.baidu.www.mplus.bean.Employee; import com. ...

  10. hadoop yarn组件介绍

    Yarn的产生 mapReduc1.0 1单点故障 2扩展效率低 3资源利用率高 降低运维成本 方便数据共享 多计算框架支持 MapReduce Spark Storm Yarn的架构图 Yarn模块 ...