大家好,我正在研究一些从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的新手。
答案 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。