Genta Hirauchi

公開日:2020/06/04
更新日:2020/08/03

【Kotlin】C++側から、Kotlinのコードを呼び出す方法を解説

  • C++側から、Kotlinのコードを呼び出したい。

ネイティブコードを利用したアプリを開発において、Java/Kotlin側からC/C++のコードは呼び出せるけれど、C/C++側からJava/Kotlinのコードを呼び出す方法がわからないという方がいらっしゃると思います。

本記事では、そんな方々に向け、C/C++側からJava/Kotlinのコードを呼び出す方法を解説致します。

なおサンプルコードでは、C++、Kotlinのコードで解説しております。

目次

Kotlin側に、C++から呼び出したい関数を実装する

まずは、Kotlin側に、C++から呼び出したい関数を実装します。

Sample.kt

それぞれ、引数&戻り値が異なる4つの関数を実装しました。各関数は、Logを出力するようにしております。

注目して頂きたいのは、@JvmStaticというアノテーションがついていることです。

C++からKotlinの関数を呼び出す際は、Static関数である必要があるため、@JvmStaticをつけて、Static関数として扱われるようにしております。

C++側に、Kotlinの関数を呼び出す処理を実装する

JavaVMの保存とJNIEnvの取得

続いて、C++側に、Kotlinの関数を呼び出す処理を実装していきます。

Kotlin側の関数の呼び出しには、FindClassや、GetStaticMethodIDなどの、JNI関数の実装がとなるため、まず、JNIEnvを取得する処理を実装します。

Sample.h

Sample.cpp

JNI_OnLoad()は、ネイティブライブラリがロードされたタイミング(System.loadLibrary等)で呼び出される関数です。JNI_OnLoad()が呼び出された際に、static変数のsavedVmに、引数で渡ってきたJavaVMを格納するようにしております。

getEnv()は、JNIEnvが必要となった時に呼ばれることを想定した関数です。static変数のsavedVmからJNIEnvを取得し、呼び出し元へ返します。

Kotlinの呼び出し処理の実装

続いて、Kotlinの呼び出し処理を実装致します。

Sample.cpp

6行目のgetEnv()で、JNIEnvを取得しております。

9行目のFindClass()では、Kotlin側の呼び出したいクラスを取得しております。引数には、クラス名を指定します。

12〜13行目は、Kotlin側に実装したfunction1()関数を呼び出す処理です。

まず、GetStaticMethodID()で、関数のIDを取得しております。
第1引数には、FindClassで取得したクラス
第2引数には、呼び出したい関数名
第3引数には、関数のシグネチャ
を指定します。

そして、CallStaticVoidMethod()に、クラスと、関数のIDを指定し、Kotlin側に実装したfunction1()関数を呼び出しております。

また、関数を呼び出した後、何の関数の呼び出しが完了したかをログで出力するようにしております。

17〜18行目は、function2() : Int関数を呼び出す処理です。function2()はIntを返す関数のため、CallStaticIntMethod()で関数の呼び出しを行なっております。

22〜25行目は、function3() : String関数を呼び出す処理です。function3()はStringを返す関数のため、CallStaticObjectMethod()で関数の呼び出しを行なっております。

ちなみに、CallStaticStringMethod()という関数は存在しません。ですので、CallStaticObjectMethod()でjobjectを取得後、jstring、const char*への変換を行った後に、ログ出力させております。

29〜31行目は、function4(num: Int, text: String)関数を呼び出す処理です。function4()は引数を必要とする関数のため、CallStaticVoidMethod()の引数に、渡したい値を指定しております。

出力結果

D/Kotlin: function1 called
D/C++: function1 finish
D/Kotlin: function2 called
D/C++: function2 finish 100
D/Kotlin: function3 called
D/C++: function3 finish function3 text
D/Kotlin: function4 called, num:200, text: function4 text
D/C++: function4 finish

以上、C++側から、Kotlinのコードを呼び出す方法の解説でした。
最後までご覧いただき、ありがとうございました。