やりたいこと
- NDK使ってる
- Kotlinでintの配列作ったけど、それをCの関数に渡したい
やること
1. kotlinでint配列を作る
MainActivity.kt
val intArray = IntArray(10000) { 10000 - it }
2. int配列をLongにする(配列のポインタを渡せるようにするため)
(ChatGPTより:Kotlinの配列をC言語が認識できる形式に変換するには、toLongArray()メソッドを使用して、配列の要素をLong型に変換し、そのポインタを取得することができます。)
MainActivity.kt
val longArray = intArray.map { it.toLong() }.toLongArray()
3. Cの関数に引数としてlong配列、long配列のサイズを渡す
MainActivity.kt
cBubbleSort(longArray, longArray.size.toLong())
第1引数にjlongArray型、第2引数にjlong型でlong配列のサイズを渡す。
(バブルソートをしているのでcBubbleSortっていう名前をつけてます)
4. CでGetArrayElementsを使って、配列のポインタを読み取る
bubble_sort.c
JNIEXPORT void JNICALL
Java_......_MainActivity_cBubbleSort(JNIEnv *env, jobject javaThis,
jlongArray long_array_pointer, jlong length){
int *cLongArray = (int *) (*env)->GetLongArrayElements(env, long_array_pointer, 0);
// ...以下好きな処理
}
5. 処理の終わりにReleaseして配列を解放する
bubble_sort.c
(*env) ->ReleaseLongArrayElements(env, long_array_pointer, (jlong *) cLongArray, 0);
全コード
MainActivity.kt
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
val intArray = IntArray(10000) { 10000 - it }
val longArray = intArray.map { it.toLong() }.toLongArray()
//Cの関数
cBubbleSort(longArray, longArray.size.toLong())
}
private external fun cBubbleSort(longArray: LongArray, length:Long)
companion object {
init {
System.loadLibrary("bubblesort")
}
}
}
bubble_sort.c
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <jni.h>
#include <android/log.h>
JNIEXPORT void JNICALL
Java_...._MainActivity_cBubbleSort(JNIEnv *env, jobject javaThis,
jlongArray long_array_pointer, jlong length) {
int *cLongArray = (int *) (*env)->GetLongArrayElements(env, long_array_pointer, 0);
int i, j, temp;
for (i = 0; i < length; i++) {
for (j = i + 1; j < length; j++) {
if (cLongArray[i] > cLongArray[j]) {
temp = cLongArray[i];
cLongArray[i] = cLongArray[j];
cLongArray[j] = temp;
}
}
}
(*env) ->ReleaseLongArrayElements(env, long_array_pointer, (jlong *) cLongArray, 0);
}
参考
https://developer.android.com/training/articles/perf-jni?hl=ja#primitive-arrays
https://stackoverflow.com/questions/67032412/how-can-i-import-arraymat-to-jni-from-kotlin
https://stackoverflow.com/questions/24649808/how-to-pass-byte-array-from-android-java-class-to-jni-c-ndk
http://web.mit.edu/javadev/doc/tutorial/native1.1/implementing/array.html