NDK - 链接共享库

时间:2018-01-24 07:39:30

标签: android android-ndk

我正在尝试将我编译的简单共享库(libhello.so)链接到我的本机C ++代码。 库libhello.so文件是:
1. get13.h

#ifndef GET13_H
#define GET13_H
int get13();
#endif

2。 get13.cpp

#include "get13.h"

int get13() {
    return 13;
}

Android文件是:
1. MyApplication / jni / Android.mk

LOCAL_PATH := $(call my-dir)

LOCAL_MODULE := libhello
LOCAL_SRC_FILES := libhello.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE    := native-lib
LOCAL_SRC_FILES := native-lib.cpp
LOCAL_SHARED_LIBRARIES := libhello
include $(BUILD_SHARED_LIBRARY)

2。所有MyApplication / JNI / Application.mk

APP_STL := gnustl_static
APP_PLATFORM := android-24

3。所有MyApplication / JNI / libhello.so
4. MyApplication / jni / get13.h - 与上面的相同 5. MyApplication / jni / native-lib.cpp

#include <jni.h>
#include <string>
#include <sstream>
extern "C"{
#include <get13.h>
JNIEXPORT jint JNICALL
Java_com_example_semko_myapplication_MainActivity_stringFromJNI(
        JNIEnv* env,
        jobject asdf) {
    get13();
    return 1;
}
}

6。所有MyApplication /应用/的build.gradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion 24
    defaultConfig {
        applicationId "com.example.semko.myapplication"
        minSdkVersion 24
        targetSdkVersion 24
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    sourceSets.main {
        jni.srcDirs = []
        jniLibs.srcDir '../jni'
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    externalNativeBuild {
        ndkBuild {
            path '../jni/Android.mk'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:24.2.1'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
}

7。所有MyApplication /应用/ SRC /主/爪哇/ com.example.semko.myapplication / MainActivity.java

package com.example.semko.myapplication;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    static {
        System.loadLibrary("native-lib");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        TextView tv = (TextView) findViewById(R.id.sample_text);
        tv.setText(Integer.toString(stringFromJNI()));
    }

    public native int stringFromJNI();
}

问题是我在gradle build in native-lib.cpp中遇到了这个错误:

Error:(10) undefined reference to `get13'
Error:error: linker command failed with exit code 1 (use -v to see invocation)

我使用Android工具链生成的android工具链编译了libhello,该脚本包含在Android NDK包中。

1 个答案:

答案 0 :(得分:2)

只有JNI函数本身应标记为extern "C",如下所示:

#include <jni.h>
#include <string>
#include <sstream>
#include <get13.h>

extern "C"
JNIEXPORT jint JNICALL
Java_com_example_semko_myapplication_MainActivity_stringFromJNI(
        JNIEnv* env,
        jobject asdf) {
    get13();
    return 1;
}

如果您使用 javah 为您准备MyApplication/jni/native-lib.h,则会有

extern "C"
JNIEXPORT jint JNICALL
Java_com_example_semko_myapplication_MainActivity_stringFromJNI(
    JNIEnv* env,
    jobject asdf);

对你而言,在 cpp 文件中,你将

#include "native-lib.h"

并且根本不需要extern "C"

要确保 Android.mk 对所有体系结构都有效,请考虑以下更改:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := libhello
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libhello.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE    := native-lib
LOCAL_SRC_FILES := native-lib.cpp
LOCAL_SHARED_LIBRARIES := libhello
include $(BUILD_SHARED_LIBRARY)

更新include $(CLEAR_VARS)之前重要部分为LOCAL_MODULE := libhello