.h: No such file or directory NDK Android - android

Hi Ivgot set the gnu make buldier Cros GCC, and javah create by cygwin, . hedaer files.
And I have the .h and .cpp in the same jni direcotry: I dont understand by this error:
make all
Building file: ../jni/com_jp_algi_CoreC.cpp
Invoking: Cross G++ Compiler
g++ -I"C:\android-ndk-r5c\platforms\android-9\arch-arm\usr\include" -O0 -g3 - Wall -c -fmessage-length=0 -MMD -MP -MF"jni/com_jp_algi_CoreC.d" - MT"jni/com_jp_algi_CoreC.d" -o "jni/com_jp_algi_CoreC.o" "../jni/com_jp_algi_CoreC.cpp"
../jni/com_jp_algi_CoreC.cpp:2:31: fatal error: com_jp_algi_CoreC.h: No such file or directory
jni/subdir.mk:18: recipe for target `jni/com_jp_algi_CoreC.o' failed
compilation terminated.
make: *** [jni/com_jp_algi_CoreC.o] Error 1
Android buldier works but ...Syas this error no implementaion....of the antive. and I must to use I thnik external make, when I create .h by javah in cygwin...maybe i convert this java project in to C++-add nature..maybe there will be problem?
Ivgot this .mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := com_jp_algi_CoreC
LOCAL_SRC_FILES := com_jp_algi_CoreC.cpp
include $(BUILD_SHARED_LIBRARY)
.cpp:
#include <com_jp_algi_CoreC.h>
/* Header for class com_jp_algi_CoreC */
extern "C" {
JNIEXPORT void JNICALL Java_com_jp_algi_CoreC_vector
(JNIEnv *env, jobject clazz, jfloatArray input){
jfloat* flt1=NULL ;
jsize size = env->GetArrayLength(input);
jint i;
// check if array size >0 and wedont cause exception
// allocate buffer for array and get data from Java array
flt1 = new jfloat[size];
env->GetFloatArrayRegion(input,0,size,flt1);
// exception check. Always use exception check
// do stuff to the array
for (i = 0 ; i < size; i++){
flt1[i] = 1;
}
// vector(flt1);
// set result to Java array and delete buffer. And exception check of course
env->SetFloatArrayRegion(input,0,size,flt1);
delete[] flt1;
// All is ok
}
JNIEXPORT void JNICALL Java_com_jp_algi_CoreC_vector2
(JNIEnv *, jobject, jfloatArray, jobjectArray);
}
.h:
/* DO NOT EDIT THIS FILE - it is machine generated /
#include
/ Header for class com_jp_algi_CoreC */
#ifndef _Included_com_jp_algi_CoreC
#define _Included_com_jp_algi_CoreC
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_jp_algi_CoreC
* Method: vector
* Signature: ([F)V
*/
JNIEXPORT void JNICALL Java_com_jp_algi_CoreC_vector
(JNIEnv *, jobject, jfloatArray);
/*
* Class: com_jp_algi_CoreC
* Method: vector2
* Signature: ([F[[F)V
*/
JNIEXPORT void JNICALL Java_com_jp_algi_CoreC_vector2
(JNIEnv *, jobject, jfloatArray, jobjectArray);
#ifdef __cplusplus
}
#endif
#endif
and this CoreC class:
package com.jp.algi;
public class CoreC {
static {
System.loadLibrary("com_jp_algi_CoreC");
}
public native void vector(float[] input);
public native void vector2(float[] input, float[][] input2);
}

Your NDK is quite old. There are many improvements and bug fixes in the new version. The latest today is r8d, and it works on Windows without cygwin.
Regarding your code, you don't need that #include statement at all, if you simply remove the first line of your .cpp file, it will compile and link correctly.

Are you sure that the "com_jp_algi_CoreC.h" file is included inside the "com_jp_algi_CoreC.cpp" file?
Does your Android.mk file look like this?
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := module_name
LOCAL_SRC_FILES := com_jp_algi_CoreC.cpp
include $(BUILD_SHARED_LIBRARY)
Is your directory structure inside the Android project like this?
jni/
├── Android.mk
├── com_jp_algi_CoreC.h
├── com_jp_algi_CoreC.cpp
Also try to run ndk-build from the root of the project instead of Eclipse and see if there is any difference.
EDIT: Using your code I've created a test Android application and compiled the native code with
ndk-build and it all works fine.

Related

Android Studio JNI with C++ UnsatisfiedLinkError

I am using Android Studio 2.1.2 I am not using Experimental Plugin
Please Check the following files and Check the error I am getting.
I solved the issue. Edited file is as follows. They way I fixed it may not be the correct way as I am setting property to use deprecated way, but it works. Experimental plugin can still be unstable. I will try with experimental plugin soon.
build.gradle from Module
sourceSets.main {
jniLibs.srcDir 'src/main/libs'
/*jni.srcDirs = [] not using this, I commented this. Please check SO links which explained when to use this and when not to use this*/
}
following 4 files are in jni folder of main
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := mylib
LOCAL_SRC_FILES := HelloJni.cpp
include $(BUILD_SHARED_LIBRARY)
Application.mk
APP_ABI := all
HelloJni.cpp
#include <jni.h>
#include <Header.h>
JNIEXPORT jstring JNICALL Java_com_example_m1035325_ndksampleapp_MainActivity_getStringFromJni(JNIEnv *env,jobject thiz)
{
env-> NewStringUTF ( "Hellofrom JNI!");
}
Header.h
#include <jni.h>;
using namespace std;
#ifndef HEADER
#define HEADER
extern "C" {
JNIEXPORT jstring JNICALL Java_com_example_m1035325_ndksampleapp_MainActivity_getStringFromJni(JNIEnv *env, jobject obj);
}
#endif //NDKSAMPLEAPP_HEADER_H
MainActicity.java
static
{
System.loadLibrary("mylib");
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tvHello=(TextView)findViewById(R.id.tvHello);
tvHello.setText(getStringFromJni());
}
public native String getStringFromJni();
Here when I hover on method getStringFromJni it shows Can't resolve corresponding JNI function
I have set NDK path in Project Structure and in Path environment variable too.
I am getting following error
Process: com.example.m1035325.ndksampleapp, PID: 12831
java.lang.UnsatisfiedLinkError: No implementation found for java.lang.String com.example.m1035325.ndksampleapp.MainActivity.getStringFromJni() (tried Java_com_example_m1035325_ndksampleapp_MainActivity_getStringFromJni and Java_com_example_m1035325_ndksampleapp_MainActivity_getStringFromJni__)
at com.example.m1035325.ndksampleapp.MainActivity.getStringFromJni(Native Method)
I searched a lot on SO also but I am not getting what I missed?
No error now , above error is fixed. Please check my answer to this question.
I think the problem is in your Android.mk file:
LOCAL_SOURCE_FILE := HelloJni.cpp
AFAIK the Android build system doesn't use variable of that name. It should be:
LOCAL_SRC_FILES := HelloJni.cpp
One important change I made is in file gradle.properties, is as follows
android.useDeprecatedNdk=true
so its related to Android Studio version 2.1.2 , for this version experimental plugin is the default option to use and the approach I am using is deprecated.
I will be trying with experimental plugin soon.

Unsatisfiedlinkerror: Unable to load custom NDK JNI library in Nfc system app

I have written a small C program using JNI which I would like to call from inside the NFC system app, specifically the NfcDispatcher.java class. I have done the following so far:
Created a /jni directory inside the /AOSP/packages/apps/Nfc/ where I have written the following JNI code. Nfc/jni/ dir has 2 files, viz mycustomlib.c and Android.mk which are as follows
mycustomlib.c at
/AOSP/packages/apps/Nfc/jni/mycustomlib.c
#include <string.h>
#include <jni.h>
jstring Java_com_android_nfc_NfcDispatcher_gettagkey( JNIEnv* env, jobject thiz, jstring tagKey )
{
// do something
return tagKey;
}
Android.mk at /AOSP/packages/apps/Nfc/jni/Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := mycustomlib
LOCAL_SRC_FILES := mycustomlib.c
include $(BUILD_SHARED_LIBRARY)
I am calling the native method "gettagkey" from inside the NfcDispatcher.java file as follows.
NfcDispatcher.java at /AOSP/packages/apps/Nfc/src/com/android/nfc/NfcDispatcher.java
public class NfcDispatcher {
..
..
public static native String gettagkey(String tagKey);
..
static class DispatchInfo {
..
}
public boolean dispatchTag(Tag tag) {
..
..
Log.d(TAG, "NFC Key Tag from C code : " + gettagkey(sb.toString()));
..
}
..
static {
System.loadLibrary("mycustomlib");
}
}
Then we compile the C code using ndk-build -C path_to_c_code
and then we did a "make -j32" to compile the code changed in the Nfc system app
and then we flash the new system.img to the Nexus 7 device. The OS boot properly but we get the following error:
W/dalvikvm( 767): Exception Ljava/lang/UnsatisfiedLinkError; thrown while initializing Lcom/android/nfc/NfcDispatcher;
E/AndroidRuntime( 767): at com.android.nfc.NfcDispatcher.<clinit>(NfcDispatcher.java:571)
E/AndroidRuntime( 767): at com.android.nfc.NfcService.<init>(NfcService.java:390)
E/AndroidRuntime( 767): at com.android.nfc.NfcApplication.onCreate(NfcApplication.java:43)
I have read all related question but I am still not sure what's happening. Does anyone have any clue? Thanks!
I have the feeling that the native library is not being loaded before the native call to the native method.
I would try to replace the gettagkey body, with the library load call, and then call the native method. Something like:
public static String gettagkey(String tagKey){
System.loadLibrary("mycustomlib");
gettagkeyNative(tagKey);
}
public static native String gettagkeyNative(String tagKey);
Don't forget to modify the native part:
#include <string.h>
#include <jni.h>
jstring Java_com_android_nfc_NfcDispatcher_gettagkeyNative( JNIEnv* env, jobject thiz, jstring tagKey)
{
// do something
return tagKey;
}
This solution would work, unless the system call to the native method requires that the gettagkey method is native.
Hope it helps!

How compile c++ project via Android NDK

I have small C++ library project with one class.
class Test
{
public:
Test(){};
~Test(){};
int SomeFunc() { return 5; }
}
I can build this class via Android NDK. (Question 1).
I can use .so file into Java application. How I can call SomeFunc method from Java code (Question 2).
Here are the steps:
1.) Create Android.mk in the project's "jni" folder:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := main_jni
LOCAL_CFLAGS :=
LOCAL_SRC_FILES := main.cpp
LOCAL_LDLIBS :=
include $(BUILD_SHARED_LIBRARY)
2.) Create main.cpp in the "jni" folder:
#include <jni.h>
using namespace std;
#ifdef __cplusplus
extern "C" {
#endif
class Test {
public:
Test(){};
~Test(){};
int SomeFunc() { return 5; }
};
jint Java_com_example_activity_MainActivity_SomeFunc(JNIEnv *env, jobject thiz)
{
Test *test = new Test();
return test->SomeFunc();
}
#ifdef __cplusplus
}
#endif
3.) Add a call to load the library in your calling activity (MainActivity.java in this example):
static {
System.loadLibrary("main_jni");
}
4.) Define the native function in the calling activity:
native int SomeFunc();
5.) Call it from the activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView text = (TextView) this.findViewById(R.id.text);
text.setText(String.valueOf(SomeFunc()));
}
6.) Run the "ndk-build" command from the project's root folder (Note: refresh the project in Eclipse after this step)
7.) Re-build and run the application
I'm not sure I understand the questions correctly but this link could be useful to you.
I'm personally do not know much of C except for the very basics, but I look forward to getting to more C with the NDK.
Whatever code you write in c you need to define it like java_urpackagename_class_methodname then before using this code u need to first create a native method in java class like public native int ABC(); telling it that you are going to use this method.To use it do create an Android.mk or Application.mk as per your need. .so will help your java class know ,what your c code wants to do.

Android: Error While Generating .so file

I'm new to Android and am trying to create a simple SDK+NDK concept. I followed the below steps:
Download NDK
Extract zip file
Create new android project.
Create new folder jni under project.
Define UI as needed.
Create a java file to call all the native methods. Declare all those methods with "native" prefix. Have static block to load library using system.loadLibrary("").
Create corresponding header file using javah -jni filename
Move the generated filename.h file to jni folder.
Write c file that includes the .h file and implements the methods in .h file and saved it.
Create mk file,with following content:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE    :=
LOCAL_SRC_FILES := .c
include $(BUILD_SHARED_LIBRARY)
Go to the project folder in command prompt
Give <ndkfolder>/ndk-build
.so file will be generated
But I got stuck in the "12" point with the following error:
**"Compile thumb : com_cts_c2dmclient_NativeLib <= com_cts_c2dmclient_NativeLib.c
jni/com_cts_c2dmclient_NativeLib.c:3:40: fatal error: com_cts_c2dmclient_NativeL
ib: No such file or directory
compilation terminated.
make: *** [obj/local/armeabi/objs/com_cts_c2dmclient_NativeLib/com_cts_c2dmclien
t_NativeLib.o] Error 1**
Note: The .h file is created successfully.
My com_exampleservice_NativeLib.c file
#include "stdio.h"
#include "malloc.h"
#include <com_exampleservice_NativeLib.h>
JNIEXPORT jint JNICALL Java_com_exampleservice_NativeLib_loop
(JNIEnv * env,jobject obj,jint v1, jint v2){
int loop;
unsigned long int *array;
if(v2 == 0){
array = (unsigned long int *)malloc(v1 * sizeof(unsigned long int));}
else if(v2 == 1)
{
array = realloc(array,sizeof(array)+v1);
}
else{
}
array[0] = 1;
array[1] = 1;
for (loop = 2; loop < v1; loop++) {
array[loop] = array[loop - 1] + array[loop - 2];
}
for (loop = 0; loop < v1; loop++) {
}
if(v2 == 2)
{
free(array);
}
return 0;
}
Your Android.mk file does not look good in your question.
Make sure that the com_exampleservice_NativeLib.h file does exist in your jni directory near your c file.
It may be necessary to add directories to the include path, like
LOCAL_C_INCLUDES += $(LOCAL_PATH)/include
Note that this $(LOCAL_C_INCLUDES) must be a list of absolute paths, not like $(LOCAL_SRC_FILES) which is $(LOCAL_PATH)-based.
Another note is that in your com_exampleservice_NativeLib.c file the use of #include directive ornamenation is not correct. It should go
#include <stdio.h>
#include <malloc.h>
#include "com_exampleservice_NativeLib.h"
See What is the difference between #include <filename> and #include "filename"? for detailed explanation.
I've just been using the NDK for the 1st time as well.
I used SWIG to avoid having to write the Java JNI code manually
I found this tutorial useful:

Jni Tutorial for android [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking us to recommend or find a tool, library or favorite off-site resource are off-topic for Stack Overflow as they tend to attract opinionated answers and spam. Instead, describe the problem and what has been done so far to solve it.
Closed 9 years ago.
Improve this question
Hi, can anyone suggest me some good resources to learn JNI for Android and some good JNI Tutorials?
Tutorial for ECLIPSE
Here is first and second small tutorials, but if you want to write a simple program that uses JNI , you may continue reading :)
Create Android application project , Once your project has been created, you’ll need to create a new folder inside the top level of the project. To do this right click on your project name → New → Folder. Name this folder jni. Than add class with name SquaredWrapper. add these code in it
package org.edwards_research.demo.jni;
public class SquaredWrapper {
// Declare native method (and make it public to expose it directly)
public static native int squared(int base);
// Provide additional functionality, that "extends" the native method
public static int to4(int base)
{
int sq = squared(base);
return squared(sq);
}
// Load library
static {
System.loadLibrary("square");
}
}
Open terminal. You must compile these code for getting header file. At first call this command.
cd src # change into the source directory
javac -d /tmp/ org/edwards_research/demo/jni/SquaredWrapper.java
Than
cd /tmp
javah -jni org.edwards_research.demo.jni.SquaredWrapper
SO you'll have header file named org.edwards_research.demo.jni.SquaredWrapper in your tmp directory.
it must be something like this
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class org_edwards_research_demo_jni_SquaredWrapper */
#ifndef _Included_org_edwards_research_demo_jni_SquaredWrapper
#define _Included_org_edwards_research_demo_jni_SquaredWrapper
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: org_edwards_research_demo_jni_SquaredWrapper
* Method: squared
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_org_edwards_1research_demo_jni_SquaredWrapper_squared
(JNIEnv *, jclass, jint);
#ifdef __cplusplus
}
#endif
#endif
change these name for some short one for your comfort, for example square.h. Copy this header file in the jni folder of your app. Than create square.c file in same folder, copy this in it.
#include "square.h"
JNIEXPORT jint JNICALL Java_com_example_android_1jni_1second_1demo_SquaredWrapper_squared
(JNIEnv * je, jclass jc, jint base)
{
return (base*base);
}
Add this in your MainActivity.java
int x = SquaredWrapper.to4(2);
x = x*2;
Add Android.mk file in jni folder with this body
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := squared
LOCAL_SRC_FILES := square.c
include $(BUILD_SHARED_LIBRARY)
It must create library from header and cpp files.
So you have only to do some configurations by looking on my first link
Now you can compile it , be sure that your library has created and your lib directory consist it.
Tutorial for Android Studio
Let's consider you have simple android application opened by Android Studio
step 1: open Your application by Android Studio
step 2: Download NDK and set the path to NDK in local properties of your application(below/above of android sdk path) like this ndk.dir=C\:\\Android\\android-ndk-r10e
P.S. for windows double // , for linux one /
step3: Add JNI folder in the app (right click on the app -> new -> folder -> JNI Folder)
step 4 Set up the Gradle by this way:
Add this code in app/build.gradle for starting NDK
sourceSets.main {
jni.srcDirs = []
jniLibs.srcDir 'src/main/libs'
}
tasks.withType(NdkCompile) { // disable automatic ndk-build call
compileTask -> compileTask.enabled = false
}
task ndkBuild(type: Exec) { // call ndk-build(.cmd) script
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
commandLine 'cmd', '/c', 'ndk-build.cmd', '-C', file('src/main').absolutePath
} else {
commandLine 'ndk-build', '-C', file('src/main').absolutePath
}
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn ndkBuild
}
step 4:
Create files Android.mk and Application.mk in JNI folder of the app with this bodies:
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := main
LOCAL_SRC_FILES := main.cpp
include $(BUILD_SHARED_LIBRARY)
Application.mk
APP_ABI := all
include $(BUILD_SHARED_LIBRARY)
In APP_ABI you choose which compilers to use. It
step 5:
We have to manually run NDK as we disable it from build.config. For creating com_example_nativedemo_app_MainActivit.h file in src\main\jn folder we have to run this command in terminal
javah -d .\jni -classpath C:\Intel\INDE\IDEintegration\android-sdk-windows\platforms\android-21\android.jar;..\..\build\intermediates\classes\debug com.example.mydemo.nativedemo.MainActivity
for windows cmd you have to give the full path of files.
For
step 6:
Add file main.cpp in JNI folder with this body:
#include <string.h>
#include <jni.h>
#include <vchat_cpptest_Hellojnicpp.h>
extern "C" {
JNIEXPORT jstring JNICALL
Java_vchat_cpptest_Hellojnicpp_stringFromJNI
(JNIEnv *env, jobject obj)
{
#ifdef __INTEL_COMPILER_UPDATE
return env->NewStringUTF("Hello from Intel C++ over JNI!");
#else
return env->NewStringUTF("Hello from default C++ over JNI!");
#endif
}
I would suggest downloading the ndk. Unzip it and browse the sample folder ndk codes. Start with the hello-jni and go further. It explains a lot with ease.
You can also browse these links and this while going through the code and keep coming back and forth.

Categories

Resources