トップ 最新 追記

Cocoa練習帳

iOS/iPhone/iPad/watchOS/tvOS/MacOSX/Android プログラミング, Objective-C, Cocoa, Swiftなど

2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|09|10|11|12|
2021|01|02|03|04|05|06|07|08|09|10|11|12|
2022|01|02|03|04|05|06|07|08|09|10|11|12|
2023|01|02|03|04|05|06|07|08|09|10|11|12|
2024|01|02|03|

2024-03-05 [Android] JNI事始め

JNI (Java Native Interface) は、Java仮想マシン (JVM) で実行されるJavaコードと、C言語などのネイティブ・プログラミング言語のコードを相互運用できるようにするためのインタフェースです。

_ 概要

ざっくりと説明すると、以下のことができるようになります。

  • JavaコードからC言語の関数が呼べる。
  • C言語のコードからJavaのメソッドが呼べる。

_ NDK (Native Development Kit)

AndroidでCやC++のコードを使えるようにするツールセットです。

_ ndk-buildとCMake

現在デフォルトのビルドツールはCMakeで、以前は、ndk-buildでした。古い資料はndk-buildを想定した説明になっていますので、CMakeに読み替えることになります。

_ Javaコードからネイティブコードを呼び出す例

以下のC言語の関数が、demoライブラリモジュールに用意されているものとします。

JNIEXPORT void JNICALL Java_com_example_Demo_printString(JNIEnv *env, jobject obj, jstring javaString)
{
    const char *nativeString = (*env)->GetStringUTFChars(env, javaString, NULL);
    printf("%s\n", nativeString);
    (*env)->ReleaseStringUTFChars(env, javaString, nativeString);
}

以下のJavaコードから呼び出します。

package com.example;
public class Demo {
    static {
        System.loadLibrary("demo");
    }
    public static native printString(String s);
    public static void main(String[] args) {
        printString("hello, world");
    }
    public static void dump() {
        System.out.println("hello, world");
    }
}

C言語の関数が、JavaのクラスDemoのメソッドとして扱われています。

_ ネイティブコードからJavaコードを呼び出す例

JNIEnvへのポインタを取得する。

JavaVM *g_vm;
JNIEnv *env = NULL;
g_vm->AttachCurrentThread((void **)&env, NULL);

Javaコードを呼び出す。

jclass jcDemo = env->FindClass("com/example/Demo");
jfieldID jfDemoDump = env->GetStaticFieldID(jcDemo, "dump", "(V)V");
env->CallStaticVoidMethod(jcDemo, jfDemoDump);
env->DeleteLocalRef(jcDemo);

デタッチする。

g_vm->DetachCurrentThread();

トップ 最新 追記