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\Release
に exe
が生成される。
exe
と同じディレクトリにGraalVMから生成したdllを配置し、コマンドプロンプトから exe
を実行すると、以下がめでたく出力された 🎉 。
17906
hello from native lib
csharpcsharpcsharp
当然といえば当然かもしれないが、GraalVM の native-image で作成したWindows dllも正常に動作する事を確認できた。
ではまた。