道化的プログラミング

GraalVMで作成したdllをC#から呼び出してみる

GraalVM CE 19でWindows版でexeファイルの生成を試したので、ddlも生成し呼び出してみる。
試した環境はWindows 10 Home Edition 64 bit。

やること

  • native-image で共有ライブラリ(dll)を生成
  • 生成したdllをC#から呼び出す

native-image で共有ライブラリを生成

基本的にこちらと同様。

ただし、native-image で共有ライブラリを生成する際に、通常のコマンドプロンプトではなく Windows SDK 7.1 Command Prompt から実行する。もしくは、通常のコマンドプロンプトから SetENV.cmd を実行後に作業をしても構わない。

生成したdllをC#から呼び出す

  • Visual Studio の新規作成にて、 C#の コンソールアプリ(.Net Framework) を選択
  • GraalVMにより生成されるdllは64bitの物のため、 構成マネージャプラットフォーム のプルダウンで 新規作成 を選択し、 x64 を選択しておく。

C#のコードは以下の通り。

using System;
using System.Runtime.InteropServices;

namespace CallDll
{
    class Program
    {
        [DllImport("libnativeimpl.dll")]
        static extern int graal_create_isolate(IntPtr prms, out IntPtr isolate, out IntPtr thread);

        [DllImport("libnativeimpl.dll")]
        static extern int Java_org_pkg_apinative_Native_add(IntPtr graal_isolatethread_t, int a, int b);

        [DllImport("libnativeimpl.dll")]
        static extern IntPtr Java_org_pkg_apinative_Native_rptstr(IntPtr graal_isolatethread_t, string str, int i);

        [DllImport("libnativeimpl.dll")]
        static extern IntPtr Java_org_pkg_apinative_Native_hello(IntPtr graal_isolatethread_t);

        [DllImport("libnativeimpl.dll")]
        static extern int graal_tear_down_isolate(IntPtr thread);

        static void Main(string[] args)
        {
            IntPtr prms = new IntPtr(0);
            IntPtr isolate = new IntPtr(0);
            IntPtr thread;

            if (graal_create_isolate(IntPtr.Zero, out isolate, out thread) != 0)
            {
                Console.WriteLine("error on isolate creation or attach");
                return;
            }

            Console.WriteLine(Java_org_pkg_apinative_Native_add(thread, 17897, 9));
            Console.WriteLine(Marshal.PtrToStringAnsi(Java_org_pkg_apinative_Native_hello(thread)));
            Console.WriteLine(Marshal.PtrToStringAnsi(Java_org_pkg_apinative_Native_rptstr(thread,"csharp", 3)));

            graal_tear_down_isolate(thread);
        }
    }
}

上記コードのビルドが正常終了すると、プロジェクトのディレクトリの bin\x64\Releaseexe が生成される。 exe と同じディレクトリにGraalVMから生成したdllを配置し、コマンドプロンプトから exe を実行すると、以下がめでたく出力された 🎉 。

17906
hello from native lib
csharpcsharpcsharp

当然といえば当然かもしれないが、GraalVM の native-image で作成したWindows dllも正常に動作する事を確認できた。

ではまた。