java調用c/c++代碼簡單實現以及遇見的坑

以下內容均來自互聯網,感謝你們的分享,我只是使用的時候看這方便,可以稱呼我“搬運工”

如有不合適的地方請與我聯繫,我會及時改正

首先你可能會遇見以下錯誤

第一個錯誤是你在vs編譯器沒有選擇使用release版的,而是用debug版的

詳細見http://blog.csdn.net/niuxinlong/article/details/4176612

F:\java>java testdll
Exception in thread "main" java.lang.UnsatisfiedLinkError: F:\java\testdll.dll:
應用程序無法啓動,因爲應用程序的並行配置不正確。有關詳細信息,請參閱應用程序事件
日誌,或使用命令行 sxstrace.exe 工具。
        at java.lang.ClassLoader$NativeLibrary.load(Native Method)
        at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1941)
        at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1857)
        at java.lang.Runtime.loadLibrary0(Runtime.java:870)
        at java.lang.System.loadLibrary(System.java:1122)
        at testdll.<clinit>(testdll.java:5)                             

第二個是在64位運行了一個32位dll

C:\testjni\testdll\x64\Debug>java testdll
Exception in thread "main" java.lang.UnsatisfiedLinkError: C:\testjni\testdll\x6
4\Debug\testdll.dll: Can't load AMD 64-bit .dll on a IA 32-bit platform
        at java.lang.ClassLoader$NativeLibrary.load(Native Method)
        at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1807)
        at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1732)
        at java.lang.Runtime.loadLibrary0(Runtime.java:823)
        at java.lang.System.loadLibrary(System.java:1028)
        at testdll.<clinit>(testdll.java:5)
Could not find the main class: testdll.  Program will exit.

 第三個當然是編碼問題嘍,編譯class時使用encoding參數

C:\Users\Dmeck\Desktop\Java\winbox>javac -encoding gb2312 Testwin.java

C:\Users\Dmeck\Desktop\Java\winbox>java Testwin
8
234
中文亂碼                                                               

 

 —————————————————————Body———————————————————————————————————

好了下面一個xp簡單實現,

環境:java1.6、MinGw、sublime、xp32、vs2008

在硬盤準備一個目錄

編寫一個java加載JNi的本地實現

testdll.java

public class testdll 
{ 
    static 
    { 
        System.loadLibrary("testdll"); 
    } 
    public native static int get(); 
    public native static void set(int i); 
    public static void main(String[] args) 
    { 
    testdll test = new testdll(); 
    test.set(10); 
    System.out.println(test.get()); 
    } 
}

cmd進入以上目錄

運行

javac testdll.java
得到class
javah testdll
得到c的頭文件

此處有兩種方式:

一個把java安裝目錄的include目錄

jni.h以及32目錄下的jni_md.h複製當前工作目錄

第二個是直接進行下一步

下一步:查看並修改剛剛編譯的頭文件testdll.h

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

#ifndef _Included_testdll
#define _Included_testdll
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     testdll
 * Method:    get
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_testdll_get
  (JNIEnv *, jclass);

/*
 * Class:     testdll
 * Method:    set
 * Signature: (I)V
 */
JNIEXPORT void JNICALL Java_testdll_set
  (JNIEnv *, jclass, jint);

#ifdef __cplusplus
}
#endif
#endif

修改全局引用爲本地目錄引用

#include <jni.h>
改爲
#include ”jni.h“

 

之後在當前目錄編寫cpp實現頭文件的方法

#include "testdll.h"
int i = 0;
JNIEXPORT jint JNICALL Java_testdll_get(JNIEnv *, jclass)
{
    return i;
}

JNIEXPORT void JNICALL Java_testdll_set(JNIEnv *, jclass, jint j)
{
    i = j;
}

 

接着運行gcc

當然本例是winxp32位默認編譯是32位dll
以下是博客參考博客地址
https://www.zhihu.com/question/36666057/answer/68516501
事實上很多情況下那樣調用都是不成功的,生成dll代碼一般這樣最完整
gcc -Wl,--add-stdcall-alias -I "C:\Program Files\Java\jdk1.6.0_31\include" -I "C:\Program Files\Java\jdk1.6.0_31\include\win32" -shared -o testdll.dll testdll.cpp

 

當你使用gcc的-m64編譯64位dll會出現
C:\Documents and Settings\Administrator\桌面\java1>gcc -m64 -Wl,--add-stdcall-al
ias -I "C:\Program Files\Java\jdk1.6.0_31\include" -I "C:\Program Files\Java\jdk
1.6.0_31\include\win32" -shared -o testdll.dll testdll.cpp
testdll.cpp:1:0: sorry, unimplemented: 64-bit mode not compiled in
 #include "testdll.h"

所以這時候用編譯工具最合適了vs2008很老,但相關博客比較多

 

 
本例是在windows下做的,生成的是dll文件。並且名稱要與java中需要調用的一致,這裏就是testdll.dll (跟testdll.java沒有關係)
把testdll.dll 拷貝到testdll.class的目錄下,java testdll運行它,就可以觀察到結果了
C:\Documents and Settings\Administrator\桌面\java1>java testdll
1000

 

 

下面介紹vs2008下編譯64位

參考http://blog.csdn.net/a_little_e/article/details/45397557

 

 

——————————————————————————END——————————————————————————————————

同樣最後我們只需要三個文件

testdll.class、testdll32.dll、testdll64.dll

當然testdll.class需要對應的testdll.java源碼,來修改

System.loadLibrary("testdll"); 
對應的加載庫

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章