jni原生方法问题

时间:2014-09-25 07:12:06

标签: java c++ java-native-interface

大家好,我正在研究一些从c ++ dll调用函数的java代码。但是可以正确调用dll中的某些函数,而其他函数则不能。   我先写一个java类从dll中包装所有函数,然后用javah生成相应的jni头文件。最后我写了c ++代码,包括生成的jni头文件。 c ++文件是用Visual Studio编写的,java代码是用Eclipse编写的。

以下是我的代码,我删除了一些不相关的代码。

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;
}

来自eclipse的错误消息是:   线程“main”中的异常java.lang.UnsatisfiedLinkError:videoDetectionJNI.VideoDetecion.getFrame(Ljava / lang / String; ILjava / lang / String;)I     在videoDetectionJNI.VideoDetecion.getFrame(本机方法)     在videoDetectionJNI.Test.main(Test.java:48)

让我痛苦的是getFrame1和getFrame2方法正常工作,但我想要的真正方法getFrame却没有。

此外,当我使用Visual Studio附加到进程java.exe来调试程序时,程序可以在cpp文件中的getFrame1和getFrame2函数中停止断点,但不会在getFrame函数的断点处停止。

somoeone可以帮助我吗?这让我很困惑。

PS。我是java的新手。

1 个答案:

答案 0 :(得分:2)

您的Java签名

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

与您的c ++实现签名不匹配。

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

将Java签名更改为非静态,或将c ++实现签名的第二个参数更改为jobject中的jclass。