Jun Wang
Jun Wang

Reputation: 707

jni native method problems

hi everyone I'm working on some java code which call functions from a c++ dll. But some functions from the dll can be called correctly, while others can not. I first write a java class wrap all the functions from the dll, then using javah generate the corresponding jni header file. At last I write c++ code include the generated jni header file. The c++ file was written in Visual Studio and the java code was written in Eclipse.

Below is my code,I have remove some irrelevant code.

Java:

public class VideoDetecion {
    static {

        System.load("dll_video_detect.dll");
        System.load("vd_jni_impl.dll");
    }

    public static native int getFrame(String videoName, int second,String frameName);
    public static native int getFrame1(String videoName);
    public static native int getFrame2(String videoName, int second);
}

c++

using cv::VideoCapture;
using cv::Mat;
using std::string;
using std::bind;
using std::shared_ptr;
using std::vector;
using std::string;

using namespace std::placeholders;


JNIEXPORT jint JNICALL Java_videoDetectionJNI_VideoDetecion_getFrame1
(JNIEnv *env, jclass, jstring videoName)
{
    //String videoName = "D:\\videos\\detect1\\0.mp4";
    shared_ptr<const char> vn(env->GetStringUTFChars(videoName, NULL), bind(&JNIEnv::ReleaseStringUTFChars, env, videoName, _1));

    int second = 10;
    string frameName = "D:\\videos\\detect1\\0-10.jpg";

    vd::getVideoFrame(string(vn.get()), second, frameName);
    return 0;
}

/*
* Class:     videoDetectionJNI_VideoDetecion
* Method:    getFrame2
* Signature: (Ljava/lang/String;I)I
*/
JNIEXPORT jint JNICALL Java_videoDetectionJNI_VideoDetecion_getFrame2
(JNIEnv *env, jclass, jstring videoName, jint second)
{
    shared_ptr<const char> vn(env->GetStringUTFChars(videoName, NULL), bind(&JNIEnv::ReleaseStringUTFChars, env, videoName, _1));


    string frameName = "D:\\videos\\detect1\\0-10.jpg";

    vd::getVideoFrame(string(vn.get()), second, frameName);
    return 0;
}



JNIEXPORT jint JNICALL Java_videoDetectionJNI_VideoDetecion_getFrame
(JNIEnv *env, jobject, jstring videoName, jint second, jstring frameName)
{
    shared_ptr<const char> vn(env->GetStringUTFChars(videoName, NULL), bind(&JNIEnv::ReleaseStringUTFChars,env, videoName,_1));
    shared_ptr<const char> fn(env->GetStringUTFChars(frameName, NULL), bind(&JNIEnv::ReleaseStringUTFChars,env,frameName,_1));


    if (videoName == NULL || frameName==NULL)
    {
        return -1;
    }

    vd::getVideoFrame(string(vn.get()), second, string(fn.get()));

    return 0;
}

The error message from eclipse was: Exception in thread "main" java.lang.UnsatisfiedLinkError: videoDetectionJNI.VideoDetecion.getFrame(Ljava/lang/String;ILjava/lang/String;)I at videoDetectionJNI.VideoDetecion.getFrame(Native Method) at videoDetectionJNI.Test.main(Test.java:48)

what makes me miserable is that the method getFrame1 and getFrame2 works correctly, but the real method getFrame that I want does not.

Furthermore, when I use Visual Studio to attach to the process java.exe to debug the program, the program can stop on breakpoint in function of getFrame1 and getFrame2 in cpp file, but would not stop on breakpoint in function of getFrame.

Can somoeone help me? It really make me confused.

ps. I'am new to java.

Upvotes: 1

Views: 2317

Answers (1)

Samhain
Samhain

Reputation: 1765

Your Java signature

public static native int getFrame(String videoName, int second,String frameName);

does not match your c++ implementation signature.

JNIEXPORT jint JNICALL Java_videoDetectionJNI_VideoDetecion_getFrame
(JNIEnv *env, jobject, jstring videoName, jint second, jstring frameName)

Either change your Java signature to be non-static, or change the second parameter of your c++ implementation signature to jclass from jobject.

Upvotes: 3

Related Questions