LoginSignup
10
14

More than 5 years have passed since last update.

C#からHaskellの関数を呼ぶ

Last updated at Posted at 2014-11-12

stackoverflowのリンク先そのまんまなんだけどひとつ詰まったのでメモ
http://stackoverflow.com/questions/16615641/calling-haskell-from-c-sharp

動作確認環境

  • Windows 7 64 bit
  • GHC 7.8.3
  • Visual Studio Express 2013 for Windows Desktop

Haskellコード

Fibonacci.hs
{-# LANGUAGE ForeignFunctionInterface #-}

-- http://stackoverflow.com/questions/16615641/calling-haskell-from-c-sharp

module Fibonacci () where

import Data.Word
import Foreign.C.Types

fibs :: [Word32]
fibs = 1 : 1 : zipWith (+) fibs (tail fibs)

fibonacci :: Word8 -> Word32
fibonacci n =
  if n > 47
    then 0
    else fibs !! (fromIntegral n)

c_fibonacci :: CUChar -> CUInt
c_fibonacci (CUChar n) = CUInt (fibonacci n)

foreign export ccall c_fibonacci :: CUChar -> CUInt

Haskellコードのビルド

ghc --make -shared Fibonacci.hs
HSdll.dllができる

C#コード

VisualStudioのコンソールアプリケーションプロジェクト

Program.cs
using System;
using System.Runtime.InteropServices;

namespace ConsoleApplication1
{
    // http://stackoverflow.com/questions/16615641/calling-haskell-from-c-sharp
    public sealed class Fibonacci : IDisposable
    {
        [DllImport("HSdll.dll", CallingConvention = CallingConvention.Cdecl)]
        private static extern void hs_init(IntPtr argc, IntPtr argv);

        [DllImport("HSdll.dll", CallingConvention = CallingConvention.Cdecl)]
        private static extern void hs_exit();

        [DllImport("HSdll.dll", CallingConvention = CallingConvention.Cdecl)]
        private static extern UInt32 c_fibonacci(byte i);

        public Fibonacci()
        {
            Console.WriteLine("Initialising DLL...");
            hs_init(IntPtr.Zero, IntPtr.Zero);
        }

        public void Dispose()
        {
            Console.WriteLine("Shutting down DLL...");
            hs_exit();
        }

        public UInt32 fibonacci(byte i)
        {
            Console.WriteLine(string.Format("Calling c_fibonacci({0})...", i));
            var result = c_fibonacci(i);
            Console.WriteLine(string.Format("Result = {0}", result));
            return result;
        }
    }

    class MainClass
    {
        public static void Main(string[] args)
        {
            using(var fib = new Fibonacci())
            {
                fib.fibonacci(10);
            }

            Console.ReadLine();
        }
    }
}

C#コードのビルド

プロジェクトのプロパティからプラットフォームターゲットをAny CPUからx64に変更してビルド(使ってるOSに合わせる?)
Haskell関係なくてC#でDLLを扱う際の基本知識なんだろうけどここがわからず詰まった(ノ∀`)

キャプチャ.PNG

実行

HSdll.dllをC#の.exeがあるフォルダにコピーして.exeを実行する

キャプチャ2.PNG

成功ヽ(^。^)ノ

Haskellのみでなにか作るのはきついんだけどこの方法でUIをC#/WPFで作って、ロジックをHaskellで記述するものが作れそう。

10
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
14