程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> 關於C# >> C#調用Haskell的方法

C#調用Haskell的方法

編輯:關於C#

【系統環境】

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(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進行編譯,編譯成功後會生成頭文件,比如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;
    } 
}

查看本欄目

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved