java.lang.UnsatisfiedLinkError: Native method not found - android

I'm trying to make a NDK application, but I get this error:
java.lang.UnsatisfiedLinkError: Native method not found: com.example.hellondk.jni.HelloNDK.hello:()I
I don't understand because the name of the C++ function is the same as the Java packagename and class
HelloNDK.cpp
#include <jni.h>
JNIEXPORT jint JNICALL Java_com_example_hellondk_jni_HelloNDK_hello(JNIEnv* env, jobject o){
return (jint) 2;
}
HelloNDK.java
package com.example.hellondk.jni;
public class HelloNDK {
public native int hello();
static {
System.loadLibrary("HelloNDK");
}
}
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := HelloNDK
LOCAL_SRC_FILES := HelloNDK.cpp
include $(BUILD_SHARED_LIBRARY)

You're exporting it as a C++ function, but the JNI linker doesn't understand C++ name mangling, so it won't be able to find it.
You can use extern "C" to have the function exported without C++ name mangling:
extern "C" JNIEXPORT jint JNICALL Java_com_example_hellondk_jni_HelloNDK_hello(JNIEnv* env, jobject o)
{
return (jint) 2;
}

Related

No implementation found

I have an Android app needs to reference and use some native C++ code. I'm an experienced Java dev, but my C++ is lacking. I'm struggling to get it to run. I'm getting the error below. If I change the name inside of loadLibrary, it crashes immediately, so I'm assuming that the load works fine. How do I fix this?
No implementation found for boolean com.example.myapplication.BamBridge.test() (tried Java_com_example_myapplication_BamBridge_test and Java_com_example_myapplication_BamBridge_test__)
public class BamBridge implements IBamBridge {
static {
System.loadLibrary("native-lib");
}
private native boolean test();
}
BAM.h:
#ifndef BAM_H
#define BAM_H
#define JNIIMPORT
#define JNIEXPORT __attribute__ ((visibility ("default")))
#define JNICALL
#include <set>
#include <vector>
#include <string>
extern "C" JNIEXPORT JNICALL bool test();
#endif
BAM.cpp
#include <cstdio>
#include <stdint.h>
#include <iostream>
#include <map>
#include "BAM.h"
#define SWAP_UINT16(val) ((val << 8) | (val >> 8))
JNIEXPORT JNICALL bool test()
{
return true;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.6.0)
add_library( # Specifies the name of the library.
native-lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
src/main/cpp/BAM.cpp )
On the C side change your function name to
Java_com_example_myapplication_BamBridge_test
As java searches for the function in the specific format.
In your Header file:
extern "C"
{
JNIEXPORT jboolean JNICALL Java_com_example_myapplication_BamBridge_test(JNIEnv *, jobject);
}
In your CPP file:
extern "C"
{
jboolean Java_com_example_myapplication_BamBridge_test(JNIEnv * env, jobject this)
{
return true;
}
}

Create a C++ class and Use that class In Another C++ Class Which contain JNI methods in ndk android

In Android, I am facing issues in connecting two cpp class in native Android. I have tested with the single class it working fine.
but when I have created another file and now facing an issue in linking it with current cpp file.
MainClass.cpp
#include <jni.h>
#include "native-handler.h"
extern "C"
JNIEXPORT jstring JNICALL
Java_com_example_fragment_SampleFragment_setTitle(JNIEnv *env,jobject instance,jobject context) {
ClassNativeHandler classNativeHandler;
return classNativeHandler.getType(env,context);
}
native-handler.cpp
#include <jni.h>
#include "native-handler.h"
jstring jstringObject;
jstring ClassNativeHandler::getType(JNIEnv *env, jobject contextObject) {
jstring jstringObject = env->NewStringUTF("Hello world");
return jstringObject;
}
void ClassNativeHandler::setType(jstring string) {
myType = string;
jstringObject = string;
}
native-handler.h
#ifndef SAMPLE_NATIVE_HANDLER_H
#define SAMPLE_NATIVE_HANDLER_H
#include <iostream>
#include <string>
class ClassNativeHandler
{
private:
jstring myType;
public:
void setType(jstring string);
jstring getType(JNIEnv *env, jobject contextObject);
jstring getHeaderName(JNIEnv *env);
};
#endif //SAMPLE_NATIVE_HANDLER_H
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := Native
LOCAL_SRC_FILES := ../cpp/mainClass.cpp
LOCAL_C_INCLUDES := ../cpp/native-handler.h
LOCAL_LDLIBS := -lz -llog -ljnigraphics
include $(BUILD_SHARED_LIBRARY)
Error : undefined reference to `ClassNativeHandler::getType(_JNIEnv*, _jobject*)'
on this line
return classNativeHandler.getType(env,context);
So I am not able to build the .so file. Please guide me
You haven't compiled native-handler.cpp. You need to specify it in LOCAL_SRC_FILES so that NDK compiles it.
LOCAL_SRC_FILES := ../cpp/mainClass.cpp ../cpp/native-handler.cpp

ndk-build error: no such file or directory

I have made a project with OpenCV and i need to use Native Code for realtime processing purpose, following the guide on this book opencv3, here is my Android.mk file:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := FinalCamJNI
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_LDLIBS := -lstdc++ # C++ standard library
LOCAL_LDLIBS += -llog # Android logging
LOCAL_LDLIBS += -lz # zlib
LOCAL_STATIC_LIBRARIES := opencv_calib3d
LOCAL_STATIC_LIBRARIES += opencv_features2d
LOCAL_STATIC_LIBRARIES += opencv_flann
LOCAL_STATIC_LIBRARIES += opencv_imgproc
LOCAL_STATIC_LIBRARIES += opencv_core
LOCAL_SRC_FILES := FinalCamJNI.cpp RecolorRCFilter.cpp
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := opencv_calib3d
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libopencv_calib3d.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := opencv_features2d
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libopencv_features2d.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := opencv_flann
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libopencv_flann.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := opencv_imgproc
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libopencv_imgproc.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := opencv_core
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libopencv_core.a
include $(PREBUILT_STATIC_LIBRARY)
and here is my Application.mk file:
APP_STL := gnustl_static # GNU STL
APP_CPPFLAGS := -frtti –fexceptions # RTTI, exceptions
APP_ABI := armeabi armeabi-v7a mips x86
APP_PLATFORM := android-8
I'm facing this error when performing ndk-build:
I have checked the directory, and ensured that i have prepared all the code file
in jni folder.
In addition, here is my implementation file:
FinalCamJNI.cpp:
#include <jni.h>
#include "RecolorRCFilter.hpp"
using namespace finalcam;
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT jlong JNICALL
Java_nahuy_hcmus_finalcam_filters_newSelf(
JNIEnv *env, jclass clazz)
{
RecolorRCFilter *self = new RecolorRCFilter();
return (jlong)self;
}
JNIEXPORT void JNICALL
Java_nahuy_hcmus_finalcam_filters_deleteSelf(
JNIEnv *env, jclass clazz, jlong selfAddr)
{
if (selfAddr != 0)
{
RecolorRCFilter *self = (RecolorRCFilter *)selfAddr;
delete self;
}
}
JNIEXPORT void JNICALL
Java_nahuy_hcmus_finalcam_filters_apply(
JNIEnv *env, jclass clazz, jlong selfAddr, jlong srcAddr,jlong dstAddr)
{
if (selfAddr != 0)
{
RecolorRCFilter *self = (RecolorRCFilter *)selfAddr;
cv::Mat &src = *(cv::Mat *)srcAddr;
cv::Mat &dst = *(cv::Mat *)dstAddr;
self->apply(src, dst);
}
}
#ifdef __cplusplus
} // extern "C"
#endif
RecolorRCFilter.hpp:
#ifndef RECOLOR_RC_FILTER
#define RECOLOR_RC_FILTER
#include <opencv2/core/core.hpp>
namespace finalcam {
class RecolorRCFilter
{
public: // All subsequent methods or variables are public.
void apply(cv::Mat &src, cv::Mat &dst);
private: // All subsequent methods or variables are private.
cv::Mat mChannels[4];
};
} // namespace secondsight
#endif // RECOLOR_RC_FILTER
RecolorRCFilter.cpp:
#include "RecolorRCFilter.hpp"
using namespace finalcam;
void RecolorRCFilter::apply(cv::Mat &src, cv::Mat &dst)
{
cv::split(src, mChannels);
cv::Mat g = mChannels[1];
cv::Mat b = mChannels[2];
// dst.g = 0.5 * src.g + 0.5 * src.b
cv::addWeighted(g, 0.5, b, 0.5, 0.0, g);
// dst.b = dst.g
g.copyTo(b);
cv::merge(mChannels, 4, dst);
}
Can anyone explain me why this happens and what I can do to solve this problem?

Android JNI ndk-build error: 'jni' has not been declared

I want to use dynamic registration in native method, so I need set JNI_onLoad function. I just write a function to get sum of two numbers. But, it can't build correctly. How can I correct the error?
This is my *.cpp file, I name this file jni.cpp
#include <jni.h>
extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) {
jni::JNIEnv& env = jni::GetEnv(*vm, jni::jni_version_1_6);
jni::jclass& nativeClass = jni::FindClass(env, "com/test/NativeClass");
#define MAKE_NATIVE_METHOD(name, sig) jni::MakeNativeMethod<decltype(name), name>( #name, sig )
jni::RegisterNatives(env, nativeClass, MAKE_NATIVE_METHOD(nativeAddTest, "(II)I") );
return JNI_VERSION_1_6;
}
jlong nativeAddTest(JNIEnv *env, jni::jobject* obj, jni::jint a, jni::jint b) {
return a+b;
}
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := test
LOCAL_SRC_FILES := jni.cpp
LOCAL_LDLIBS := -L/ndk-path/sources/cxx-stl/stlport/libs/armeabi
include $(BUILD_SHARED_LIBRARY)
When I use ndk-build command, it's wrong. But I really dont't konw the reason...
D:\WorkSpaces\Test\app\src\main\jni>ndk-build
[x86] Compile++ : test <= jni.cpp
D:/WorkSpaces/Test/app/src/main/jni/jni.cpp: In function 'jint JNI_OnLoad(JavaVM*, void*)':
D:/WorkSpaces/Test/app/src/main/jni/jni.cpp:9:5: error: 'jni' has not been declared
jni::JNIEnv& env = jni::GetEnv(*vm, jni::jni_version_1_6);
^
D:/WorkSpaces/Test/app/src/main/jni/jni.cpp:9:18: error: 'env' was not declared in this scope
jni::JNIEnv& env = jni::GetEnv(*vm, jni::jni_version_1_6);
....
It seems can't find jni.h, but I already have #include<jni.h>
In Android NDK, <jni.h> does not define a jni namespace. Simply remove all jni::
#include <jni.h>
extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) {
JNIEnv env;
vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6);
jclass nativeClass = env->FindClass("com/test/NativeClass");
… and so on.
Add header location to your android.mk
LOCAL_C_INCLUDES := "path to your header location"

Can't separate header and source files in JNI

in JNI folder:
//File foo.h
#ifndef FOO_H_
#define FOO_H_
class Foo {
public:
Foo();
void Funny();
};
#endif /* FOO_H_ */
//File foo.cpp
#include "foo.h"
cv::string bar[1] = {"FOO"};
Foo::Foo() {
}
void Foo::Funny() {
}
Then, when I call:
Foo foo;
foo.Funny();
ndk-build complains:
error: undefined reference to 'Foo::Foo()
error: undefined reference to 'Foo::Funny()
However, if I put the function implementation in the header file like this:
#ifndef FOO_H_
#define FOO_H_
class Foo {
public:
Foo();
void Funny();
};
Foo::Foo() {
}
void Foo::Funny() {
}
#endif /* FOO_H_ */
The compiler then happily compiles my code.
How could I separate function prototypes and their implementation in JNI?
UPDATE: Here's my Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
OPENCV_LIB_TYPE:=STATIC
OPENCV_INSTALL_MODULES:=on
include ../../sdk/native/jni/OpenCV.mk
LOCAL_SRC_FILES := native.cpp
LOCAL_C_INCLUDES += $(LOCAL_PATH)
LOCAL_LDLIBS += -llog -ldl
LOCAL_MODULE := native
include $(BUILD_SHARED_LIBRARY)
The undefined reference is outputted by the linker, not by the Compiler. This means there is no translation unit containing the functions you have used in your code. Telling by the Android.mk file I'd say foo.cpp is missing in your LOCAL_SRC_FILES Statement.

Categories

Resources