LoginSignup
0
0

More than 1 year has passed since last update.

[Android][NDK]Kotlinのint配列をCに渡したいとき

Posted at

やりたいこと

  • 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

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0