2017-12-09 5 views
0

Androidスタジオ3.0にアップデートしました。アンドロイドアプリのネイティブコンポーネントをビルドするため、非推奨のNDKからCMakeに移行しようとしています。AndroidスタジオネイティブCMakeネイティブの実装が見つかりません

私はhttps://developer.android.com/studio/projects/configure-cmake.htmlのガイドに従い、ここに私のCMakeLists.txtファイルできました:

cmake_minimum_required(VERSION 3.4.1) 
add_library(# Specifies the name of the library. 
     myappNative 

     # Sets the library as a shared library. 
     SHARED 

     # Provides a relative path to your source file(s). 
     src/main/cpp/src 
     ) 


include_directories(src/main/cpp/include) 
SET_TARGET_PROPERTIES(myappNative PROPERTIES LINKER_LANGUAGE CXX) 

(最後の行は、チュートリアルではありませんが、私はそれを追加する前にエラーを得ていました)。ここ

は私のフォルダ構造である:ここ

enter image description here

は私のネイティブメソッドである:

/* DO NOT EDIT THIS FILE - it is machine generated */ 
#include <jni.h> 
/* Header for class com_myapp_system_Native */ 

#ifndef _Included_com_myapp_system_Native 
#define _Included_com_myapp_system_Native 
#ifdef __cplusplus 
extern "C" { 
#endif 
/* 
* Class:  com_myapp_system_Native 
* Method: sign 
* Signature: ([Ljava/lang/String;)Ljava/lang/String; 
*/ 
JNIEXPORT jstring JNICALL Java_com_myapp_system_Native_sign 
    (JNIEnv *, jclass, jobjectArray); 

#ifdef __cplusplus 
} 
#endif 
#endif 

:ここ

public class Native { 

    static { 
     System.loadLibrary("myappNative"); 
    } 

    public native static String sign(String[] tokens); 
} 

は(javahによって生成された)私のヘッダファイルでありますそして私は対応するC++ファイルをコンパイルする正しく。私のAPKにはlibmyapp.soファイルが含まれていますが、すべてが期待どおりに見えます。マイアプリのビルド、それが実行を開始、それはライブラリをロードします(logcat)

D/dalvikvm: Trying to load lib /data/app-lib/com.myapp.myapp-1/libmyappNative.so 0x41e09aa0 
D/dalvikvm: Added shared lib /data/app-lib/com.myapp.myapp-1/libmyappNative.so 0x41e09aa0 

その後、私はネイティブメソッドを呼び出そう瞬間が、私はこれを取得:

この続く
W/dalvikvm: No implementation found for native Lcom/myapp/system/Native;.sign:([Ljava/lang/String;)Ljava/lang/String; 

E/AndroidRuntime: FATAL EXCEPTION: com.myapp.client.queue 
            Process: com.myapp.myapp, PID: 19542 
            java.lang.UnsatisfiedLinkError: Native method not found: com.myapp.system.Native.sign:([Ljava/lang/String;)Ljava/lang/String; 
             at com.myapp.system.Native.sign(Native Method) 
[...] 

アプリがクラッシュします。私はAndroid NDK C++ JNI (no implementation found for native...)を含むこれに関する多くの質問を見てきましたが、それらの解決策も役に立ちません。ログで

、私は以下を参照してください。

:app:externalNativeBuildDebug 
Build myappNative armeabi-v7a 
[1/1] Linking CXX shared library ../../../../build/intermediates/cmake/debug/obj/armeabi-v7a/libmyappNative.so 
:app:compileDebugSources 

大丈夫のようですどの。

私はまた、ProGuardのは、メソッド名をマングルであるかもしれないことをどこかで読んだので、私は、あまりにもそのためのルールを追加しました:

-keep class com.myapp.system.Native

それはしかし何かを変更した場合、私は知りません。ここで

はまた私のGradleファイルの関連一部です:

android { 
    compileSdkVersion 26 
    buildToolsVersion '26.0.2' 

    defaultConfig { 
     applicationId "com.myapp.myapp" 
     minSdkVersion 16 
     targetSdkVersion 26 
     versionCode 2043 
     versionName "2.1" 
     ndk { 
      moduleName "myappNative" 
      cFlags "-DNATIVE_DEBUG=1" 
     } 

    } 


    externalNativeBuild { 
     cmake { 
      path 'CMakeLists.txt' 
     } 
    } 
} 

、私はまた、JNI_OnLoadメソッドを実装し、ヘッダにそれを宣言しようとしましたが、どちらか見られていないようですこれは私の構成で一般的な何かのための手がかりはなく、具体的な方法かもしれません:なぜ私の母国方法を見つけることができないのAndroid

No JNI_OnLoad found in /data/app-lib/com.myapp.myapp-2/libmyappNative.so 0x41e10aa0, skipping init 

のですか?

答えて

1

明らかに、チュートリアル(SET_TARGET_PROPERTIESを追加したもの)にないエラーが鍵です。

私はこの問題を発見しました。私のCMakeLists.txtでは、私はsrc/main/cpp/srcというフォルダを参照していました。実際にはファイルをコンパイルしていませんでした。私はnm(ARM版)とチェックしており、.soファイルの中に実際の方法は見当たりませんでした。次に、CPPファイル(コンパイルすべきではない)にいくつかのガベージを追加しましたが、ビルドは正常に完了しました。コンパイル中のCPPファイルに関する私の最初の仮定は正しくありませんでした。ツールチェーンは私のファイルをコンパイルしようとしていませんでした。

add_library(# Specifies the name of the library. 
     myappNative 

     # Sets the library as a shared library. 
     SHARED 

     # Provides a relative path to your source file(s). 
     src/main/cpp/src/com_myapp_system_Native.cpp 
     src/main/cpp/src/sha256.c 
     ) 

私はどのようにフォルダを含めるべきかわかりません。私は明示的にコンパイルするためにファイルをリストする必要があります。私はsrc/main/cpp/srcsrc/main/cpp/src/*src/main/cpp/src/*.cppを試しましたが、どれもうまくいかないようです。ファイルを変更した後、私のアプリケーションが起動して(そして、ネイティブコンポーネントをロードする)正しく。

+1

名前で明示的にファイルを一覧表示するには、受け入れられていても、それに対処するための推奨方法があります。ワイルドカードが必然的に必要な場合は、['file(GLOB ...)'](https://stackoverflow.com/a/3201211/192373)を使うことができます。 –

+0

@AlexCohn私は実際にCMakeには新しく、「火と忘れ」の方法でフォルダを追加するのは良い考えです。しかし、明示的に参照する方法があれば、私はこのようにしておきます。コメントありがとう:) –

0

ねえ、include_directoryを代わりにtarget_include_directoriesを使用してください。この関数を使用すると、そのライブラリに個人的にディレクトリを追加します。それでもソースファイルに関するエラーが発生する場合は、{CMAKE_CURRENT_SOURCE_DIR}をソースパス行に追加してください。できます !

関連する問題