jni本机方法问题 我正在研究一些java代码,它调用C++的函数库。但是,dll中的某些函数可以正确调用,而其他函数则不能。 我首先编写一个java类来包装dll中的所有函数,然后使用javah生成相应的jni头文件。最后,我编写C++代码,包括生成的JNI头文件。C++文件是在VisualStudio中编写的,java代码是在Eclipse中编写的。
下面是我的代码,我删除了一些不相关的代码 爪哇:jni本机方法问题 我正在研究一些java代码,它调用C++的函数库。但是,dll中的某些函数可以正确调用,而其他函数则不能。 我首先编写一个java类来包装dll中的所有函数,然后使用javah生成相应的jni头文件。最后,我编写C++代码,包括生成的JNI头文件。C++文件是在VisualStudio中编写的,java代码是在Eclipse中编写的。,java,c++,java-native-interface,Java,C++,Java Native Interface,下面是我的代码,我删除了一些不相关的代码 爪哇: 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 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++
使用cv::VideoCapture;
使用cv::Mat;
使用std::string;
使用std::bind;
使用std::shared_ptr;
使用std::vector;
使用std::string;
使用名称空间std::占位符;
JNIEXPORT jint JNICALL Java\u VideoDetection JNI\u VideoDetection\u getFrame1
(JNIEnv*env、jclass、jstring videoName)
{
//String videoName=“D:\\videos\\detect1\\0.mp4”;
共享的\u ptr vn(env->GetStringUTFChars(videoName,NULL),bind(&JNIEnv::ReleaseStringUTFChars,env,videoName,_1));
int秒=10;
string frameName=“D:\\videos\\detect1\\0-10.jpg”;
vd::getVideoFrame(字符串(vn.get()),第二个,frameName);
返回0;
}
/*
*类别:视频检测JNI\U视频检测
*方法:getFrame2
*签名:(Ljava/lang/String;I)I
*/
JNIEXPORT jint JNICALL Java\u VideoDetection JNI\u VideoDetection\u getFrame2
(JNIEnv*env、jclass、jstring videoName、jint second)
{
共享的\u ptr vn(env->GetStringUTFChars(videoName,NULL),bind(&JNIEnv::ReleaseStringUTFChars,env,videoName,_1));
string frameName=“D:\\videos\\detect1\\0-10.jpg”;
vd::getVideoFrame(字符串(vn.get()),第二个,frameName);
返回0;
}
JNIEXPORT jint JNICALL Java\u VideoDetection JNI\u VideoDetection\u getFrame
(JNIEnv*env、jobject、jstring videoName、jint second、jstring frameName)
{
共享的\u ptr vn(env->GetStringUTFChars(videoName,NULL),bind(&JNIEnv::ReleaseStringUTFChars,env,videoName,_1));
共享\u ptr fn(env->GetStringUTFChars(frameName,NULL),bind(&JNIEnv::ReleaseStringUTFChars,env,frameName,_1));
if(videoName==NULL | | frameName==NULL)
{
返回-1;
}
vd::getVideoFrame(字符串(vn.get()),第二个,字符串(fn.get());
返回0;
}
来自eclipse的错误消息是:
线程“main”java.lang.UnsatifiedLinkError中出现异常:videoDetectionJNI.VideoDetection.getFrame(Ljava/lang/String;ILjava/lang/String;)I
在videoDetectionJNI.VideoDetection.getFrame(本机方法)
位于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++实现签名的第二个参数从JojEng./P>改为JCype。i、 e.您认为已导出的符号是否已实际导出?其次,您必须重新运行
javah
,因为最后一个函数的签名与针对.java文件运行它时得到的签名不匹配(即使它被放入videoDetectionJNI
包中)。5 4 0000121 java\u videoDetectionJNI\u VideoDetection\u getFrame0=@ILT+540(java\u videoDetectionJNI\u VideoDetection\u getFrame0)6 5 0000126 Java\u VideoDetection JNI\u VideoDetection\u getFrame1=@ILT+545(Java\u VideoDetection JNI\u VideoDetection\u getFrame1)7 6 00001230 Java\u VideoDetection JNI\u getFrame2=@ILT+555(Java\u VideoDetection JNI\u VideoDetection\u getFrame2)导出的函数是getFrame0
,但是在JNI中查找的函数是getFrame
。此外,当您在C++中编译代码时,它会被名称损坏,从而可以通过函数签名(例如重载方法)来引用。如果您错误地声明了其中一个参数的类型,例如使用jobject
而不是jclass
作为方法的第二个参数,则.h
文件中的定义告诉编译器不要损坏函数(声明周围的extern“C”{
)不匹配,因此该方法最终被损坏,因此无法找到您为Java\u videodetection JNI\u videodetection\u getFrame
发布的源代码表明第二个参数是jobject
,它与.h
不匹配。这将导致函数无法导出。是的。Java类中的方法getFrame以前是非静态的,所以生成的签名是(jobject)。后来,我将方法getFrame更改为静态方法,所以生成的签名是(jclass)。但是该方法的实现仍然是(jobject)我不会因为方法的签名改变而改变它。所以这里有一个问题,在javah生成的.h中声明了一个函数,但我没有实现它(虽然我有一个名为getFrame的函数,但它不是在.h文件中声明的),编译器不会给出警告或错误消息。
JNIEXPORT jint JNICALL Java_videoDetectionJNI_VideoDetecion_getFrame
(JNIEnv *env, jobject, jstring videoName, jint second, jstring frameName)