zoukankan      html  css  js  c++  java
  • 经过实际验证的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,示例代码如下:

    Haskell代码

    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(1, 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进行编译,编译成功后会生成头文件,比如buildlibpandoc.dlllibpandoc.dll-tmpLibPandoc_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源代码

  • 相关阅读:
    ZeptoLab Code Rush 2015
    UVa 10048 Audiophobia【Floyd】
    POJ 1847 Tram【Floyd】
    UVa 247 Calling Circles【传递闭包】
    UVa 1395 Slim Span【最小生成树】
    HDU 4006 The kth great number【优先队列】
    UVa 674 Coin Change【记忆化搜索】
    UVa 10285 Longest Run on a Snowboard【记忆化搜索】
    【NOIP2016提高A组模拟9.28】求导
    【NOIP2012模拟10.9】电费结算
  • 原文地址:https://www.cnblogs.com/dudu/p/csharp-call-haskell.html
Copyright © 2011-2022 走看看