I'm trying to call the stringFromJNI2(env, obj) function from the NDKTest.c file.
Here is the code for the NDKTest.c File:
#include <string.h>
#include <stdio.h>
#include <jni.h>
#include <limits.h>
JNIEXPORT jstring JNICALL
Java_com_test_ndk_NDKTest_stringFromJNI2( JNIEnv *env,
jobject thiz )
{
#if defined(__arm__)
#if defined(__ARM_ARCH_7A__)
#if defined(__ARM_NEON__)
#if defined(__ARM_PCS_VFP)
#define ABI "armeabi-v7a/NEON (hard-float)"
#else
#define ABI "armeabi-v7a/NEON"
#endif
#else
#if defined(__ARM_PCS_VFP)
#define ABI "armeabi-v7a (hard-float)"
#else
#define ABI "armeabi-v7a"
#endif
#endif
#else
#define ABI "armeabi"
#endif
#elif defined(__i386__)
#define ABI "x86"
#elif defined(__x86_64__)
#define ABI "x86_64"
#elif defined(__mips64) /* mips64el-* toolchain defines __mips__ too */
#define ABI "mips64"
#elif defined(__mips__)
#define ABI "mips"
#elif defined(__aarch64__)
#define ABI "arm64-v8a"
#else
#define ABI "unknown"
#endif
return (*env)->NewStringUTF(env, "Hello from JNI2 ! Compiled with ABI " ABI ".");
}
Here is the code for the NDKTest.h File:
#ifndef NDKTEST_H_
#define NDKTEST_H_
#include <jni.h>
#include <string>
const std::allocator<char> & stringFromJNI2(JNIEnv *env, jobject thiz);
#endif
Here is the code for the TestNDK.cpp File:
#include <string.h>
#include <jni.h>
#include <string>
#include <jni.h>
#include "NDKTest.h"
extern "C" {
stringFromJNI2(JNIEnv *env, jobject obj);
}
JNIEXPORT jstring JNICALL
Java_com_test_ndk_TestNDK_main(JNIEnv *env, jobject obj) {
#if defined(__arm__)
#if defined(__ARM_ARCH_7A__)
#if defined(__ARM_NEON__)
#define ABI "armeabi-v7a/NEON"
#else
#define ABI "armeabi-v7a"
#endif
#else
#define ABI "armeabi"
#endif
#elif defined(__i386__)
#define ABI "x86"
#endif
//std::string hello("Hello from JNI ! Compiled with ABI " ABI ".");
std::string hello(stringFromJNI2(env, obj));
return env->NewStringUTF(hello.c_str());
}
Here is the code for the TestNDK.java File:
package com.test.ndk;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
public class TestNDK extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/* Retrieve our TextView and set its content.
* the text is retrieved by calling a native
* function.
*/
setContentView(R.layout.activity_hello_jni);
TextView tv = (TextView)findViewById(R.id.hello_textview);
tv.setText( main() );
public native String main();
static {
//System.loadLibrary("main");
System.loadLibrary("TestNDK");
}
}
Here are the lines in the CMakeLists.txt File:
cmake_minimum_required(VERSION 3.4.1)
add_library(testNDK SHARED
TestNDK.cpp
NDKTest.c)
# Include libraries needed for testNDK lib
target_link_libraries(testNDK
android
log)
Here is the code from the build.gradle file:
apply plugin: 'com.android.application'
android {
compileSdkVersion 25
buildToolsVersion '25.0.2'
defaultConfig {
applicationId 'com.test.ndk'
minSdkVersion 23
targetSdkVersion 25
versionCode 1
versionName "1.0"
externalNativeBuild {
cmake {
arguments '-DANDROID_TOOLCHAIN=clang'
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
externalNativeBuild {
cmake {
path "src/main/cpp/CMakeLists.txt"
}
}
productFlavors {
arm7 {
// in the future, ndk.abiFilter might also work
ndk {
abiFilter 'armeabi-v7a'
}
}
arm8 {
ndk {
abiFilters 'arm64-v8a'
}
}
arm {
ndk {
abiFilter 'armeabi'
}
}
x86 {
ndk {
abiFilter 'x86'
}
}
x86_64 {
ndk {
abiFilter 'x86_64'
}
}
mips {
ndk {
abiFilters 'mips', 'mips64'
}
}
universal {
ndk {
abiFilters 'mips', 'mips64', 'x86', 'x86_64'
}
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:25.2.0'
compile 'com.android.support.constraint:constraint-layout:1.0.1'
}
I'm currently getting the following errors "Error:(10, 1) error: C++ requires a type specifier for all declarations" & "Error:(29, 23) error: call to 'stringFromJNI2' is ambiguous" due to the following line of code in TestNDK.cpp:
stringFromJNI2(JNIEnv *env, jobject obj);
This line of the code in located in the extern "C" block of code. I'm trying to call the stringFromJni2() function in the NDKTest.c file from the TestNDK.cpp file. How would I fix the current errors I'm getting and call the stringFromJNI2() function in the NDKTest.c file to display the "Hello from JNI2 ! Compiled with ABI" string. Any help on this would be greatly appreciated. Thanks.
I'm trying to call the stringFromJni2() function in the NDKTest.c file from the TestNDK.cpp file.
You should declare the function prototype from NDKTest.c
in NDKTest.h
. So the header should look like this:
#ifndef NDKTEST_H_
#define NDKTEST_H_
#include <jni.h>
#ifdef __cplusplus
extern "C" {
#endif
jstring Java_com_test_ndk_NDKTest_stringFromJNI2(JNIEnv *env, jobject thiz);
#ifdef __cplusplus
}
#endif
#endif
TestNDK.cpp
:
#include <jni.h>
#include "NDKTest.h"
#ifdef __cplusplus
extern "C" {
#endif
// remove this declaration
// stringFromJNI2(JNIEnv *env, jobject obj);
JNIEXPORT jstring JNICALL
Java_com_test_ndk_TestNDK_main(JNIEnv *env, jobject obj) {
#if defined(__arm__)
#if defined(__ARM_ARCH_7A__)
#if defined(__ARM_NEON__)
#define ABI "armeabi-v7a/NEON"
#else
#define ABI "armeabi-v7a"
#endif
#else
#define ABI "armeabi"
#endif
#elif defined(__i386__)
#define ABI "x86"
#endif
return Java_com_test_ndk_NDKTest_stringFromJNI2(env, obj);
}
#ifdef __cplusplus
}
#endif
TestNDK.java
:
// the library name has to be the same
// as you defined in CMakeLists.txt
static {
System.loadLibrary("testNDK");
}
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.