Java中調用c/c++語言出現Exception in thread "main" java.lang.UnsatisfiedLinkError: Test.testPrint(Ljava/lang/String;)V...錯誤


錯誤:

Exception in thread "main" java.lang.UnsatisfiedLinkError: Test.testPrint(Ljava/lang/String;)V
at Test.testPrint(Native Method)
at Test.main(Test.java:8)

解決方法:

昨天一天都在想辦法解決這個問題,操作步驟按照教程來的,怎么會出錯呢?
想了半天,覺得還是dll文件生成的不對。所以,最后決定把codeblocks換成visual c++來編譯生成dll文件,最后一試成功了。

 

------------------------------我是分割線----------------------------------------------------------------------------------------------------------------

Java中如何調用c/c++

1、首先打開eclipse,新建一個eclipse工程,編寫一個java類。

如下所示:

public class Test {
public native void testPrint(String str);//1


public static void main(String[] args){
System.loadLibrary("TestAgain");//2


Test test = new Test();
test.testPrint("this is a test");
}

}

分析這個程序,1處使用native關鍵字申明了一個本地方法,這個方法我們在后面要用c/c++實現

2處則是在java中通過libname:TestAgain加載本地方法庫。

這里可以使用System.loadLibrary("xxx");//xxx是生成的dll文件的名字加載本地方法庫,也可以通過System.load("E:/eclipseWork/Test/TestAgain.dll")來加載本地方法庫,load方法里面需要填寫絕對路徑。

 

2、然后使用 javac -d . Test.java 生成類文件

3、再使用 javah -jni Test 生成.h文件 

生成的.h文件如下

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Test */

#ifndef _Included_Test
#define _Included_Test
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: Test
* Method: testPrint
* Signature: (Ljava/lang/String;)V//1
*/
JNIEXPORT void JNICALL Java_Test_testPrint
(JNIEnv *, jobject, jstring); //2

#ifdef __cplusplus
}
#endif
#endif

這個和我們平常的.h文件沒有什么差別,都是用來申明函數的,不過它是機器自動生成的,所以不要修改。

1處,是一個標記符,當從本地方法端訪問java端的時候就會用到。

java類型 Signature 備注
boolean Z  
byte B  
char C  
short S  
int I  
long L  
float F  
double D  
void V  
object L用/分割的完整類名 例如: Ljava/lang/String表示String類型
Array [簽名 例如: [I表示int數組, [Ljava/lang/String表示String數組
Method (參數簽名)返回類型簽名 例如: ([I)I表示參數類型為int數組, 返回int類型的方法

(表格摘自http://www.cnblogs.com/icejoywoo/archive/2012/02/22/2363709.html)

2處是函數申明,我們在c/c++中需要實現

4、用visual c++新建一個dll工程。test.h文件中包含#include <jni.h>,包含的jni.h存在於JDK安裝目錄下的include下面。需要將他們添加進來。

Tools->Options->Directories,新建Directions。

再就是用c/c++實現本地方法,注意.c/.cpp中的函數名必須和.h中的函數名一致

下面是.cpp的代碼

#include "windows.h"
#include "Test.h"
#include "iostream.h"
/*
* Class: Test
* Method: testPrint
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_Test_testPrint(JNIEnv * env, jobject obj, jstring str){
const char *msg;
msg = env->GetStringUTFChars(str,0);
cout<<"the msg is"<<endl;
cout<<msg<<endl;
env->ReleaseStringUTFChars(str,msg);
}

5、編譯通過生成TestAgain.dll。將它復制到之前建的eclipse工程根目錄下面

6、回到eclipse界面,F5刷新工程,然后run。結果如下

這樣就實現了在Java中調用c/c++。

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM