2014-09-25 82 views
1

嗨,大家好我正在從C++ dll調用函數的一些java代碼。但是可以正確調用dll的某些函數,而其他函數則不能。 我先寫了一個java類,將所有的函數從dll中包裝好,然後用javah生成相應的jni頭文件。最後我寫的C++代碼包括生成的jni頭文件。 C++文件是用Visual Studio編寫的,而java代碼是用Eclipse編寫的。jni原生方法問題

下面是我的代碼,我已經刪除了一些不相關的代碼。

爪哇:

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

從蝕的錯誤信息是: 異常在線程 「主要」 java.lang.UnsatisfiedLinkError中:videoDetectionJNI.VideoDetecion.getFrame(Ljava /郎/ String; ILjava/lang/String;)I at videoDetectionJNI.VideoDetecion.getFrame(Native Method) at videoDetectionJNI.Test.main(Test.java:48)

讓我感到悲慘的是方法getFrame1和getFrame2正常工作,但我想要的真正的方法getFrame沒有。此外,當我使用Visual Studio附加到進程java.exe來調試程序時,程序可以在cpp文件中的getFrame1和getFrame2函數中停止斷點,但不會停止在getFrame函數的斷點處。

somoeone可以幫助我嗎?這真的讓我感到困惑。

ps。我是新來的Java。

+0

dumpbin/exports vd_jni_impl.dll顯示什麼?即您認爲導出實際導出的符號?其次,你重新運行'javah'是因爲最後一個函數的簽名與在.java文件中運行它的內容不匹配(即使它放在'videoDetectionJNI'包中)。 – Petesh 2014-09-25 08:25:13

+0

5 4 00001221 Java_videoDetectionJNI_VideoDetecion_getFrame0 = @ ILT + 540(Java_videoDetectionJNI_VideoDetecion_getFrame0) 6 5 00001226 Java_videoDetectionJNI_VideoDetecion_getFrame1 = @ ILT + 545(Java_videoDetectionJNI_VideoDetecion_getFrame1) 7 6 000Java_videoDetectionJNI_VideoDetecion_getFrame2 = @ ILT + 555(Java_videoDetectionJNI_VideoDetecion_getFrame2) – 2014-09-25 08:44:13

+0

三個功能全部出口。我已經重新運行了javah(通過Eclipse),並且頭文件是最新的 – 2014-09-25 08:45:56

回答

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。