这里是另一种方法,使用Java-C粘合文件中的全局静态变量,通过引用将变量传递给C,并将从C更改的变量返回给Java。但需要两个Java函数调用。
以下是在Kotlin中使用Android开发的示例:
首先,C代码(一个简单的通过引用增加变量的函数):
// lib.c
void cfunction(int *number)
{
*number += 1;
}
通常我们会有另一个C代码,像胶水一样,用来处理Java的特性
static int number;
void cfunction(int *);
JNIEXPORT void JNICALL
Java_com_example_someapp_MainActivity_inc(JNIEnv* env, jobject thiz, jint value)
{
number = value;
cfunction(&number);
}
JNIEXPORT jint JNICALL
Java_com_example_someapp_MainActivity_getnumber(JNIEnv* env, jobject thiz)
{
return number;
}
它使用一个全局变量
number
(仅限于文件glue.c内部访问,感谢
static
关键字),并且可以通过getter函数
getnumber
在外部访问。所以基本上我们需要一个额外的函数和一个静态全局变量来调用一个期望指针并改变其引用的C库。
一个
CMakeLists.txt
看起来会像这样:
cmake_minimum_required(VERSION 3.18.1)
project("someapp")
add_library(somelib SHARED
glue.c
lib.c)
最后是Android(Kotlin)部分:
package com.example.someapp
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
inc(4)
val number = getnumber()
Toast.makeText(this, number.toString(), Toast.LENGTH_LONG).show()
}
external fun inc(number: Int)
external fun getnumber(): Int
companion object {
init {
System.loadLibrary("somelib")
}
}
}
应该显示
5
。