jni原生方法问题

jni native method problems

本文关键字:问题 方法 原生 jni      更新时间:2023-10-16

大家好,我正在研究一些从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.UnsisfiedLinkError异常: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的函数中停止。

有人能帮我吗?这真的让我很困惑。

ps。我是java新手。

您的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。