我正在尝试从 NDKTest.c 文件调用 stringFromJNI2(env, obj) 函数。
这是 NDKTest.c 文件的代码:
#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 ".");
}
这是 NDKTest.h 文件的代码:
#ifndef NDKTEST_H_
#define NDKTEST_H_
#include <jni.h>
#include <string>
const std::allocator<char> & stringFromJNI2(JNIEnv *env, jobject thiz);
#endif
这是 TestNDK.cpp 文件的代码:
#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());
}
这是 TestNDK.java 文件的代码:
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");
}
}
这是 CMakeLists.txt 文件中的行:
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)
这是来自 build.gradle 文件的代码:
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'
}
我目前收到以下错误“错误:(10, 1) 错误:C++ 需要所有声明的类型说明符”和“错误:(29, 23) 错误:调用‘stringFromJNI2’不明确”由于到 TestNDK.cpp 中的以下代码行:
stringFromJNI2(JNIEnv *env, jobject obj);
这行代码位于 extern "C"代码块中。我正在尝试从 TestNDK.cpp 文件调用 NDKTest.c 文件中的 stringFromJni2() 函数。我将如何修复我遇到的当前错误并调用 NDKTest.c 文件中的 stringFromJNI2() 函数以显示“Hello from JNI2!使用 ABI 编译”字符串。对此的任何帮助将不胜感激。谢谢。
最佳答案
I'm trying to call the stringFromJni2() function in the NDKTest.c file from the TestNDK.cpp file.
您应该在 NDKTest.h
中声明来自 NDKTest.c
的函数原型(prototype)。所以标题应该是这样的:
#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");
}
关于java - 在 Android JNI/NDK 代码中从 C++ 函数调用 C 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43327690/