大家好,我正在编写一些从 C++ dll 调用函数的 Java 代码。但是dll中的一些函数可以被正确调用,而另一些则不能。 我先写了一个java类,把dll中的所有函数封装起来,然后用javah生成对应的jni头文件。最后,我编写了包含生成的 jni 头文件的 C++ 代码。 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( native 方法) 在 videoDetectionJNI.Test.main(Test.java:48)
让我痛苦的是方法getFrame1和getFrame2工作正常,但我想要的真正方法getFrame却没有。
此外,当我使用Visual Studio附加到进程java.exe调试程序时,程序可以在cpp文件中的getFrame1和getFrame2函数断点处停止,但不会在getFrame函数断点处停止。
有人能帮我吗?这真的让我很困惑。
附言。我是 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。
关于java - jni本地方法问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26032713/