I am getting a SIGABORT when calling GetDoubleField().
I have written a small sample program to show the issue...
MainActivity.java
package net.directionalsystems.jnitest;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
// Used to load the 'native-lib' library on application startup.
static {
System.loadLibrary("native-lib");
}
private static final String TAG = "Mainactivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Example of a call to a native method
TextView tv = findViewById(R.id.sample_text);
JniComms jc = new JniComms();
jc.latitude = 10;
jc.logitude = 20;
jc.txtLocation = "Hello";
try {
tv.setText(stringFromJNI(jc));
}
catch (Exception e)
{
Log.e(TAG, "onCreate: ", e);
}
}
/**
* A native method that is implemented by the 'native-lib' native library,
* which is packaged with this application.
*/
public native String stringFromJNI(JniComms jc);
}
JniComms.java
package net.directionalsystems.jnitest;
import java.util.ArrayList;
public class JniComms
{
public double latitude;
public double logitude;
public String txtLocation;
//public ArrayList<BleStatus> bleStatusArray;
}
native-lib.cpp
#include <jni.h>
#include <string>
extern "C" JNIEXPORT jstring JNICALL
Java_net_directionalsystems_jnitest_MainActivity_stringFromJNI(
JNIEnv *env,
jobject jo,
jobject jc)
{
jclass jcClass = env->GetObjectClass(jc);
jfieldID iId = env->GetFieldID(jcClass, "latitude", "D");
// Executing the next line causes SIGABORT
jdouble latitude = env->GetDoubleField(jcClass, iId);
std::string hello = "Hello world";
return env->NewStringUTF(hello.c_str());
}
The build.gradle file follows...
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
buildToolsVersion "29.0.2"
defaultConfig {
applicationId "net.directionalsystems.jnitest"
minSdkVersion 23
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
cppFlags ""
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
customDebugType {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
debuggable true
}
}
externalNativeBuild {
cmake {
path "src/main/cpp/CMakeLists.txt"
version "3.10.2"
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
}
This has got to be something simple and stupid that I am doing.
I would like to debug into the NDK code but all I get is the jni.h file displayed and cannot step into the JNI code itself. Having that capability may give me an idea of what is wrong.
Many thanks for any help.
Best regards, Jackie
When reading an instance (non-static) field you're supposed to pass the object, not the class.
So replace:
jdouble latitude = env->GetDoubleField(jcClass, iId);
with:
jdouble latitude = env->GetDoubleField(jc, iId);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.