2011年5月5日木曜日

Scalaで書いたコードをdllにしてC#から呼んでみる。

最近、Scalaが楽しくていろいろ勉強しているのだが、そもそもC#erな僕はJavaをよく知らないため、この「Javaを知らない」というのはちょくちょく学習のハードルになったりする。

いろいろScalaについて調べてみたところ、JVMだけでなく、.netでも動くということらしいので、勝手知ったる.net上で勉強したら、やりやすいかもしれないぞ、と思った。

そこで、Scalaで書いたコードをdllにし、C#で呼び出してみる。

前提条件として、JDKとScala2.7.7がすでにインストールされていること。OSはWindows 7。
(Scala2.8.1だと、後述するscala-msilの実行時にエラーになった)

まずは、ScalaのコードをMSILという.net framework 用の中間言語化するための"scala-msil"をインストールする。
これはsbazを使って簡単にインストールできる。

コマンドラインプロンプトを管理者権限で実行し、以下のコマンドを叩けば良い。

>sbaz install scala-msil

これでインストールできているはずだ(2.8.1でもここまでは上手く行った)。

続いて、C#から呼び出されることになるプログラムをScalaで書く。

package CalcUtil {
    class Calc {
        def hoge(num:Int): Int = {
            num * 10
        }
    }
}

ファイル名は「CalcUtil.scala」とした。
検証していないが、パッケージ名とファイル名が大文字小文字含めて一致しないといけない、という記事をどこかで読んだので、注意する必要があるみたい。

さて。このソースをMSILにコンパイルしよう。

>scalac-net CalcUtil.scala

これでOK

ちなみに、scala-msilが入っていれば、

>scalac -target:msil (以下略

でもできるみたい。

これで 「CalcUtil.msil」ができあがったはずである。

あとは、.net Frameworkのilasm.exeでdll化すれば良い。

コマンドは以下のような感じ。

>C:\Windows\Microsoft.NET\Framework\v2.0.50727\ilasm.exe /DLL CalcUtil.msil

Microsoft (R) .NET Framework IL Assembler. Version 2.0.50727.5420
Copyright (c) Microsoft Corporation. All rights reserved.
Assembling 'CalcUtil.msil' to DLL --> 'CalcUtil.dll'
Source file is ANSI

Assembled method CalcUtil.Calc::.ctor
Assembled method CalcUtil.Calc::hoge
Assembled method CalcUtil.Calc::$tag
Creating PE file

Emitting classes:
Class 1: CalcUtil.Calc

Emitting fields and methods:
Global
Class 1 Methods: 3;

Emitting events and properties:
Global
Class 1
Writing PE file
Operation completed successfully

これで「CalcUtil.dll」が完成!! ヽ(´ー`)ノバンザーイ

さあ、あとはこれをC#から呼び出すだけだ。

VisualStudioを起動し、参照設定でCalcUtil.dllを読み込もう。


で、以下のコードを書く。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CalcUtil;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Calc c = new Calc();
            Console.WriteLine(c.hoge(99).ToString());
        }
    }
}

ここでビルドを実行すると、エラーが出た。


Scalaのオブジェクトを理解できないようだ。

scala-msilのインストールが無事に完了していれば、 %SCALA_HOME%¥libの配下にこれを解決するためのdllが入っているはずである。

predef.dll と scalaruntime.dllである。

これらを参照に追加しよう。


これで問題なくビルドが通るはずだ。

実行すると……。


キタ━━━━(゚∀゚)━━━━ッ!!

これでミッション完了!!

しかし、これだけの手間をかけてnet上でScala動かしてゴリゴリ勉強しようとは思わんなー。

素直にJVM上でInteliJなどのIDEのお世話になりながら勉強しようと思う。

0 件のコメント:

コメントを投稿