2016-02-12 91 views
1

我是NDK和JNI的新手,不確定如何解決此錯誤。我手動將libMathFuncLib.so,mathFuncsLibs.cpp和MathFuncLibs.h文件複製到Eclipse項目中。當我運行這個命令'ndk-build'並返回'workspace/test/jni/TestMath.cpp時:error:'Add'沒有在這個範圍內聲明。'Eclipse NDK構建錯誤'添加'未在此範圍內聲明

這裏是我的文件夾結構:

-test 
    |__src 
     |__ExecuteTest.java 
     |__MainActivity.java 

    |__jni 
     |__Android.mk 
     |__Application.mk 
     |__TestMath.cpp 

    |__libs 
     |__armeabi 

    |__myLibs 
     |__armeabi 
      |__libMathFuncLib.so 

    |__myNatives 
     |__MathFuncLibs.cpp 
     |__MathFuncLib.h 

這裏是MathFuncLib.h文件:

//This is static library example  

#ifndef MathFuncLib_INCLUDED 
#define MathFuncLib_INCLUDED 

#ifdef __cplusplus 
extern "C" { 
#endif 

    class MyMathFunc 
    { 

    public: 

     static int Add(int a, int b); 
     static int Subtract(int a, int b); 
     static int Multiply(int a, int b); 
     static double Divide(int a, int b); 

    }; 

#ifdef __cplusplus 
} // extern "C" 
#endif 
#endif 

這裏是MathFuncLib.cpp文件:

#include "MathFuncLib.h" 

    int MyMathFunc::Add(int a, int b) 
    { 
     return a + b; 
    } 

    int MyMathFunc::Subtract(int a, int b) 
    { 
     return a - b; 
    } 

    int MyMathFunc::Multiply(int a, int b) 
    { 
     return a * b; 
    } 

    double MyMathFunc::Divide(int a, int b) 
    { 
     return a/b; 
    } 

這裏是MainActivity.java文件:

package com.example.test; 

import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.view.Menu; 
import android.view.MenuItem; 
import android.widget.TextView;//to use TextView 
import android.widget.GridLayout.LayoutParams;//to use LayoutParams 

public class MainActivity extends AppCompatActivity { 


    @Override 
    protected void onDestroy() { 
     // TODO Auto-generated method stub 
     super.onDestroy(); 
    } 

    @Override 
    protected void onStop() { 
     // TODO Auto-generated method stub 
     super.onStop(); 
    } 

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

     int retVal = 0; 
     ExecuteTest et = new ExecuteTest(); 
     retVal = et.TestAdd();    

     TextView tv = new TextView(this); 
     LayoutParams lp = new LayoutParams(); 
     lp.setMargins(150, 50, 200, 0); 
     tv.setLayoutParams(lp); 
     tv.setText(String.valueOf(retVal)); 
     setContentView(tv); 

    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.main, menu); 
     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     // Handle action bar item clicks here. The action bar will 
     // automatically handle clicks on the Home/Up button, so long 
     // as you specify a parent activity in AndroidManifest.xml. 
     int id = item.getItemId(); 
     if (id == R.id.action_settings) { 
      return true; 
     } 
     return super.onOptionsItemSelected(item); 
    } 
} 

這裏是ExecuteTest.java文件:

package com.example.test; 

import android.util.Log; 

public class ExecuteTest { 

    public int ReturnValue(){ 
     return 50; 
    } 

    public native int TestAdd(); 

    static 
    { 
     System.loadLibrary("MathFuncLib"); 
     System.loadLibrary("Arithmetic"); 

     Log.i ("ExecuteTest", "Shared Libs loaded"); 
    }  
} 

這裏是TestMath.cpp文件:

#include <jni.h> 
#include <string.h> 
#include <android/log.h> 
#include "../myNatives/MathFuncLib.h" 

extern "C" 
{ 

    JNIEXPORT int JNICALL Java_com_example_test_ExecuteTest_TestAdd(JNIEnv *env, jobject obj) 
    { 
     __android_log_print(ANDROID_LOG_INFO, "Test", "Inside TestAdd()"); 

     int retVal= Add(50,50);//Add(,) is a method inside MathFuncLib.so file 
     return retVal; 
    } 
} 

這裏我們我的Android.mk文件:

LOCAL_PATH := $(call my-dir) 

include $(CLEAR_VARS) 
LOCAL_MODULE := MathFuncLib-prebuilt 
LOCAL_SRC_FILES := ../myLibs/armeabi/libMathFuncLib.so 
include $(PREBUILT_SHARED_LIBRARY) 

include $(CLEAR_VARS) 
LOCAL_MODULE := Arithmetic 
LOCAL_SRC_FILES := TestMath.cpp 
LOCAL_LDLIBS := -llog -lz 

include $(BUILD_SHARED_LIBRARY) 

這裏是應用.mk文件:

APP_STL := gnustl_shared 

謝謝。

回答

0

這是

Application.mk

APP_ABI   := x86    ## -- set to whatever platform you need 
APP_PLATFORM := android-9 
APP_STL   := stlport_static ## -- USE IT 

正確的形式。

至於Android.mk你將需要2,因爲我看到你想要使用兩個項目,以建立一個解決方案 -

原生(非JNI)庫

第二本地(JNI)庫,加載第一個,並通過JNI使其可用於JAVA

Application.mk應該重複。

Android.mk(所述天然一部分)

include $(CLEAR_VARS) 

# 
# --------------- C/C++ Project settings --------------- 
# 
LOCAL_PATH    := _path_to__myNatives 

# Application/Library Name 
LOCAL_MODULE   := MathFunc 

# Project Source files 
LOCAL_SRC_FILES   := MathFuncLibs.cpp 

# Compiler Flags 
LOCAL_CFLAGS   := -mfpu=neon 

### THIS BIT BELOW IS IMPORTANT -- used so that projects that include this build output will find the correct headers ### 

# Location of headers 
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/. 
# 
# ------------------------- .. ---------------------------- 
# 

include $(BUILD_STATIC_LIBRARY) 

您將使用Eclipse,這樣你就可以找到_path_to__myNatives/OBJ /本地/ $(TARGET_ARCH_ABI)/libMathFunc.a輸出。在本例中$(TARGET_ARCH_ABI)的計算結果爲x86。 需要爲您的平臺構建一次(在Application.mk中指定)。

Android.mk(在本地JNI部分)

與 「共享」 取代 「靜態」(不含引號OFC)

# 
# -------------- Dependant Static Libraries Linkage --------------- 
# 
include $(CLEAR_VARS) 

LOCAL_PATH    := _path_to__myNatives 

LOCAL_MODULE   := MathFuncLib ## can be different from the previous module name definition in Android.mk or can be the same 

LOCAL_SRC_FILES   := $(LOCAL_PATH)/obj/local/$(TARGET_ARCH_ABI)/libMathFunc.a 

include $(PREBUILT_STATIC_LIBRARY) 
# 
# ------------------------- .. ---------------------------- 
# 

# 
# --------------- C/C++ Project settings ---------------- 
# 
include $(CLEAR_VARS) 

LOCAL_PATH    := _path_to___jni 

# Application/Library Name 
LOCAL_MODULE   := Arithmetic 

# Project Source files 
LOCAL_SRC_FILES   := TestMath.cpp 

# Compiler Flags 
LOCAL_CFLAGS   := -mfpu=neon 

LOCAL_LDLIBS   := -llog -lz 

# Static Libraries 
LOCAL_STATIC_LIBRARIES := MathFuncLib # must be exactly the same as in THIS .mk file 

# Shared Libraries 
#LOCAL_SHARED_LIBRARIES := MathFuncLib # must be exactly the same as in THIS .mk file 
# 
# ------------------------- .. ---------------------------- 
# 

include $(BUILD_SHARED_LIBRARY) 
+0

很抱歉的誤解。我不認爲我想爲兩個項目構建解決方案。我只是想讓Java調用C++庫中的Math(int,int),所以我只是將該C++庫構建到共享庫中,並將其複製到Eclipse項目文件夾myNatives。之所以我將MathFuncLib.cpp複製到myNatives文件夾中,是因爲我不確定,所以我只是做了它。據我所知,我需要JNI部分調用Java的C++函數Math(int,int)。所以基本上就是這樣。 –

+0

我想你誤解了我的答案。如果你不想要2個庫,只需在第二個Android.mk文件中包含源代碼,並刪除「---依賴靜態庫鏈接---」部分 –

+0

感謝回覆。非常感謝。 –

0

想和大家分享我的固定。

1)在我的MyMathFunc.h文件中,我不應該使用「extern C」,因爲C不支持class。如果想要使用「extern C」,那麼我必須刪除類聲明。

2)需要更改Android.mk和Application.mk文件。

Android.mk文件:

LOCAL_PATH := $(call my-dir)  
include $(CLEAR_VARS) 

LOCAL_MODULE := MathFuncLib 
LOCAL_SRC_FILES := ../myLibs/armeabi/libMathFuncLib.so 
include $(PREBUILT_SHARED_LIBRARY) 

include $(CLEAR_VARS)  
LOCAL_SHARED_LIBRARIES := MathFuncLib  
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../myNatives/  
LOCAL_MODULE := Arithmetic 
LOCAL_SRC_FILES := TestMath.cpp  
LOCAL_LDLIBS := -llog -lz 

#Tell it to build an APK  
include $(BUILD_SHARED_LIBRARY) 

Application.mk文件:

APP_STL := gnustl_shared