经过实际验证的C#调用Haskell的方法
【系统环境】
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;
}
}
【参考资料】
Call a Haskell function in .NET
经过实际验证的C#调用Haskell的方法的更多相关文章
- 困扰多日的C#调用Haskell问题竟然是Windows的一个坑
最近一直被C#调用Haskell时的“尝试读取或写入受保护的内存”问题所困扰(详见C#调用haskell遭遇Attempted to read or write protected memory,C# ...
- C#调用haskell遭遇Attempted to read or write protected memory
1. Haskell的代码如下: 上面的代码中readMarkdown与writeHtmlString是pandoc中的函数,newString的作用是将String转换为IO CString. 2. ...
- js调用php和php调用js的方法举例
js调用php和php调用js的方法举例1 JS方式调用PHP文件并取得php中的值 举一个简单的例子来说明: 如在页面a.html中用下面这句调用: <script type="te ...
- Jquery Ajax调用aspx页面方法
Jquery Ajax调用aspx页面方法 在asp.net webform开发中,用jQuery ajax传值一般有几种玩法 1)普通玩法:通过一般处理程序ashx进行处理: 2)高级玩法:通过as ...
- zabbix调用api检索方法
环境 zabbix:172.16.128.16:zabbix_web:172.16.16.16/zabbix 用户名:Admin 密码:zabbix 获取的数据仅做参考,以Linux发送HTTP的PO ...
- ASP.Net:Javascript 通过PageMethods 调用后端WebMethod方法 + 多线程数据处理 示例
ASP.Net:Javascript 通过PageMethods 调用后端WebMethod方法 + 多线程数据处理 示例 2012年04月27日 16:59:16 奋斗的小壁虎 阅读数:4500 ...
- SNF快速开发平台MVC-EasyUI3.9之-WebApi和MVC-controller层接收的json字符串的取值方法和调用后台服务方法
最近项目组很多人问我,从前台页面传到后台controller控制层或者WebApi 时如何取值和运算操作. 今天就都大家一个在框架内一个取值技巧 前台JS调用代码: 1.下面是选中一行数据后右键点击时 ...
- Struts2 调用非execute方法
调用非execute方法 1)如果你的Action类是继承自ActionSupport的话,确切的说是重写了execute方法,ActionSupport里的默认实现就是返回"success ...
- Python开发基础-Day20继承实现原理、子类调用父类的方法、封装
继承实现原理 python中的类可以同时继承多个父类,继承的顺序有两种:深度优先和广度优先. 一般来讲,经典类在多继承的情况下会按照深度优先的方式查找,新式类会按照广度优先的方式查找 示例解析: 没有 ...
随机推荐
- Activiti5 添加/查询审批批注(审批意见)
Activiti5 添加/查询审批批注 Activiti 工作流开发,23张表中,act_hi_commit 中,用于保存流程审核的批注信息: 调用: taskServer.addComment ...
- 利用PHP脚本辅助MySQL数据库管理5-检查异常数据
<?php $dbi = new DbMysql; $dbi->dbh = 'mysql://root:mysql@127.0.0.1/coffeetest'; $map = array( ...
- NotificationMangerService处理显示通知
设置——>应用——>点击“已下载”列表中的任一APP,如图: 代码位置:Settings\src\com\android\settings\applications\InstalledA ...
- 人类及其他物种基因组DNA之问
问题1 : 不同人类个体的基因组长度总长是不是一样,如果不一样,那么人类基因组长度排序和范围区间是如何控制的?最短是多少,最长是多少?如果一样,如何理解基因的插入与缺失,INDEL等现象,如何平衡的呢 ...
- IPutils
package com.mmall.util; import lombok.extern.slf4j.Slf4j;import org.apache.commons.lang3.StringUtils ...
- python早期看书笔记
- java web实践
语言:java.javascript 软件:eclipse.mysql 环境配置:下载jdk:配置jdk环境变量.相关教程:https://jingyan.baidu.com/article/db55 ...
- web-Amazon
一 准备实验数据 1.1.下载数据 wget http://snap.stanford.edu/data/amazon/all.txt.gz 1.2.数据分析 1.2.1.数据格式 product/p ...
- Linux未安装上传下载的插件,怎么进行文件的上传下载
首先连上服务: 然后Alt+p,打开SFTp窗口: 例如,我们今天要往tomcat的webappmu目录下上传一个文件: 先pwd,查看我们Linux上所处的目录:pwd 然后进入到tomcat的we ...
- 在vue中使用后台提供 的token验证方式总结及使用方法
token是相对会叫安全的使用暗码形式的数据传输,由后台产生,并且传输到前台,前台可以将保存,在前台每次发送请求的时候可以携带token,后台可以对token进行验证,通过验证的通过请求可以对数据进行 ...