JWorld@TW the best professional Java site in Taiwan
      註冊 | 登入 | 全文檢索 | 排行榜  

» JWorld@TW » Java SE 討論區  

按列印兼容模式列印這個話題 列印話題    把這個話題寄給朋友 寄給朋友   
reply to topicthreaded modego to previous topicgo to next topic
本主題所含的標籤
無標籤
作者 請問JNI運用在JAVA 與 c++該如何作DLL檔? [精華]
vincentwei



發文: 0
積分: 0
於 2003-12-23 01:24 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
請問一下, 我看http://java.sun.com/docs/books/tutorial/native1.1/TOC.htm

的資料, 他說C/C++都是java 的native language, 但是, 他只提到用C 去作一個

library, 確沒提到如何用C++做一個library, DLL檔, 請問有人有這個經驗嗎 ??

我是用microsoft VC 6.0, 請高手指教一下....


reply to postreply to post
作者 Re:請問JNI運用在JAVA 與 c++該如何作DLL檔? [Re:vincentwei]
scottlai





發文: 136
積分: 4
於 2003-12-23 04:59 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
*.cpp

extern "C"
{

JNIEXPORT ....
.......
......
}


reply to postreply to post
作者 Re:請問JNI運用在JAVA 與 c++該如何作DLL檔? [Re:vincentwei]
vincentwei



發文: 0
積分: 0
於 2003-12-23 09:27 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
#include <jni.h>
#include "HelloJNI.h"
#include <iostream.h>

JNIEXPORT void JNICALL
Java_HelloWorld_displayHelloWorld(JNIEnv *env, jobject obj)
{
cout << "Hello world!\n";
return;
}

當我在#include <jni.h> compile就error了... @@


reply to postreply to post
作者 Re:請問JNI運用在JAVA 與 c++該如何作DLL檔? [Re:vincentwei]
Duncan

還隱隱作痛

版主

發文: 7816
積分: 39
於 2003-12-23 12:15 user profilesend a private message to usersend email to Duncanreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
vincentwei wrote:
#include <jni.h>
#include "HelloJNI.h"
#include <iostream.h>

JNIEXPORT void JNICALL
Java_HelloWorld_displayHelloWorld(JNIEnv *env, jobject obj)
{
cout << "Hello world!\n";
return;
}

當我在#include <jni.h> compile就error了... @@


因為 VC 找不到 jni.h 這個檔案。改成 #include "jni.h" 並在 VC IDE 裡設定一下 header directory 使其包含 jni.h 所在的目錄(%JDK_HOME%\include, %JDK_HOME%\include\win32)。


reply to postreply to post

給我
辣味豆腐 其餘免談
作者 Re:請問JNI運用在JAVA 與 c++該如何作DLL檔? [Re:vincentwei]
newworld





發文: 3
積分: 1
於 2003-12-28 15:22 user profilesend a private message to usersend email to newworldreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
[JNI的研究]
以下是我個人的經驗
雖然JAVA的程式都必須在JAVA的虛擬機器上執行,但是我們可以在這部機器中打一個洞,讓JAVA程式可以直接溝通實際的機器
JNI是一種讓JAVA程式可以外接外部程式的一種機制,讓JAVA程式更具有擴充性,下面將示範一個簡單的範例,這個範例中說明JAVA程式如何與C語言接軌,事實上昨天所談的Prolog就是利用這種方式使Java程式可以使用prolog,透過dll和native的方式來達成這項任務,經過這樣的測試與實驗之後讓我不得不佩服java這個程式語言
你不需要擔心程式方面的問題,因為底下的程式架構都相當簡單,主要只是讓我們體驗一下

工具介紹:我將使用visual c++ 6.0來製作dll,使用java sdk 1.4來編譯我的java

java部分的實作
程式碼如下(HelloWorld.java):
1
2
3
4
5
6
7
8
9
10
11
class HelloWorld { 
public native void displayHelloWorld();←左方的native型態是通知Java這個函數會使用到外部函數 
 
static { 
System.loadLibrary("hello"); ←左方的程式碼代表我要載入hello.dll的動態連結,hello.dll的製作我在稍後會做介紹 
} 
 
public static void main(String[] args) { 
new HelloWorld().displayHelloWorld(); 
} 
}


當你完成上述的程式之後,將這個程式存檔為'HelloWorld.java'先用'javac HelloWorld.java'這個指令將它組譯成HelloWorld.class,然後使用'javah HelloWorld'產生HelloWorld.h,在HelloWorld.h中我們知道我們要實作一個函數Java_HelloWorld_displayHelloWorld(JNIEnv *, jobject); 接下來我將介紹如何完成這個函數
實作生平的第一個dll,在之前知道在windows和linux下有一種叫dll,動態連結的機制,但是一直不曉得到底它是怎麼做的,今天將要實作第一個這樣的東西
我會盡量將東西描述清楚,因為這是我第一次的經驗
首先啟動visual c++ 6.0,在檔案中選擇新增,然後在project中選擇Win32 Dynamic-Link Library這個選項,然後填寫你專案的名稱'hello',按下'Ok',請選擇An empty Dll project這一選項,然後按'Finish'再按下'Ok',我們要從頭開始。
經過上述動作之後我們就會得到一個空的專案資料,然後我們需要增加一些程式到我們的專案中,在這之前我們先處理好我們的.h檔,首先先到你安裝java JDK的目錄下找到include的資料夾,為了以後撰寫程式方便,將這個目錄下的所有檔案複製一份到你安裝visual c++ 6.0目錄下VC98\Include裡面,預設路徑為C:\Program Files\Microsoft Visual Studio\VC98\Include,將資料複製到此資料夾中,並將原本放在win32中的jawt_md.h和jni_md.h複製一份至C:\Program Files\Microsoft Visual Studio\VC98\Include
完成這些前置動作之後,再來將我們剛剛產生的HelloWorld.h加入我們的Header Files中,並新增一個.c的檔案HelloWorldImp.c,然後到上方的功能表中Build選則'Build hello.dll',然後你將會得到一個hello.dll在專案目錄下的Debug\hello.dll,到此為止,如果順利你應該的到dll檔

程式碼如下(HelloWorldImp.c):
1
2
3
4
5
6
7
8
9
10
#include 
#include "HelloWorld.h" 
#include 
 
JNIEXPORT void JNICALL 
Java_HelloWorld_displayHelloWorld(JNIEnv *env, jobject obj) 
{ 
printf("HelloWorld"); 
return; 
}


程式碼如下(HelloWorld.h)
1
2
3
4
5
6
7
8
9
10
11
12
/* DO NOT EDIT THIS FILE - it is machine generated */ #include 
/* Header for class HelloWorld */ #ifndef _Included_HelloWorld #define _Included_HelloWorld 
#ifdef __cplusplus extern "C" { #endif 
/* 
* Class: HelloWorld 
* Method: displayHelloWorld 
* Signature: ()V 
*/ 
JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld 
(JNIEnv *, jobject); 
#ifdef __cplusplus } #endif 
#endif


然後將hello.dll和HelloWorld.class放在同一個目錄下,執行java HelloWorld,出現列印HelloWorld在畫面上的結果
以上這是一個小小的範例,目的只是在做一個小小的實驗,因為沒有一個人會因為要列印一串自救去呼叫C語言來幫你做事,而會直接使用System.out.print("HelloWorld"),比較快一點
透過以上這個小實驗讓我們知道java和c之間是有辦法互通的,因此或許java可以透過這個方式與作業系統之間有更密切的互動

[註]以上資料出自於http://140.129.25.117:8000/swpweb/mycalendar.py?who_calendar=mycalendar,這是我個人的研究心得報告,剛好我有研究到這個所以就將文章放到這邊與大家分享(檔案位置2003年12月26所撰寫的心得)


newworld edited on 2003-12-28 15:50
reply to postreply to post
作者 Re:請問JNI運用在JAVA 與 c++該如何作DLL檔? [Re:newworld]
chen





發文: 62
積分: 0
於 2004-12-27 17:15 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
newworld先進~~
真的是謝謝您的指教,經由您的文章,小弟真的在jni的了解上,又多了一層認識,像您這樣不吝惜的將您所了解的,與大家來分享,相信這亦是社群的真正本質,也相信經由您的分享,在社群裡面,必定會有更多的先進一同來為台灣的軟體產業貢獻自己的心力~~^^


reply to postreply to post
作者 Re:請問JNI運用在JAVA 與 c++該如何作DLL檔? [Re:vincentwei]
foxty





發文: 4
積分: 0
於 2005-01-14 03:48 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
我也非常感谢 newworld 写出这篇帖子,让我实质性的了解到JNI。谢谢!

reply to postreply to post
作者 Re:請問JNI運用在JAVA 與 c++該如何作DLL檔? [Re:vincentwei]
alpha_dyz





發文: 34
積分: 0
於 2005-01-21 14:44 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
谢谢你!

reply to postreply to post
作者 Re:請問JNI運用在JAVA 與 c++該如何作DLL檔? [Re:vincentwei]
tomorrovvv





發文: 1
積分: 0
於 2005-02-01 09:30 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
非常感謝,
如果要引入繫統的DLL應該也是一樣的吧?


reply to postreply to post
作者 Re:請問JNI運用在JAVA 與 c++該如何作DLL檔? [Re:vincentwei]
hyj_dx





發文: 16
積分: 0
於 2005-06-15 16:56 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
这是自己写c++文件,
如果调用别人已经编译好的.dll文件,给你接口,怎么去实现


reply to postreply to post
作者 Re:請問JNI運用在JAVA 與 c++該如何作DLL檔? [Re:hyj_dx]
Duncan

還隱隱作痛

版主

發文: 7816
積分: 39
於 2005-06-15 21:28 user profilesend a private message to usersend email to Duncanreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
hyj_dx wrote:
这是自己写c++文件,
如果调用别人已经编译好的.dll文件,给你接口,怎么去实现


不考慮 MSVM。
如果 third-party dll 只是一般的 dll 沒有遵照 JNI native function 的命名規則,你就必須自己寫 native method,然後在 JNI function 裡去使用 third-party dll。


reply to postreply to post

給我
辣味豆腐 其餘免談
作者 Re:請問JNI運用在JAVA 與 c++該如何作DLL檔? [Re:vincentwei]
hyj_dx





發文: 16
積分: 0
於 2005-06-20 17:16 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
我说的就是没有遵照jni native function 的命名规则的dll档,
也就是怎么在自己写的native method 再去调用dll档


reply to postreply to post
作者 Re:請問JNI運用在JAVA 與 c++該如何作DLL檔? [Re:hyj_dx]
Duncan

還隱隱作痛

版主

發文: 7816
積分: 39
於 2005-06-20 17:25 user profilesend a private message to usersend email to Duncanreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
hyj_dx wrote:
我说的就是没有遵照jni native function 的命名规则的dll档,
也就是怎么在自己写的native method 再去调用dll档


如果別人有一併給你 import library(就是給你一個 xxx.dll 與一個對應的 xxx.lib),你撰寫自己的 JNI function(for native method) 裡去 call dll 裡的函式,就如同你使用一般的 library 一樣。

若是沒有給 import library,你得用 win32 的 LoadLibrary 去打開 dll,然後以 GetProcAddress 取得函式在 dll 裡的位置,透過 function pointer 來 invoke 此函式。


reply to postreply to post

給我
辣味豆腐 其餘免談
作者 Re:請問JNI運用在JAVA 與 c++該如何作DLL檔? [Re:vincentwei]
bgyeats





發文: 197
積分: 0
於 2006-08-03 18:25 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
求救
有一個java 呼叫 dll 問題
我現在有一隻asp,我要把他翻成Java版..
這一隻dll的功能是呼叫他會回傳一個字串回來
但是他的用法很奇怪..明明是UCCom.dll
但是他卻用 CreateObject ("UCCom.UCQuery")

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Sub GetUnlockCodeRealTime( )
  Dim obj
  Dim strCommand
  
  set obj=Server.CreateObject ("UCCom.UCQuery")
 
   bOk = False
  strCommand = "&b=2&g=3"
 
  UnlockKeyCode = obj.GetCode("127.0.0.1", strCommand)
  
  ' Maybe hide part of unlock code for display for sercurity reason
  DisplayUnlockCode = UnlockKeyCode
    
  if UnlockKeyCode <> "ERROR" then
    bOk = True
  end if
  
  set obj = nothing
  
End Sub


我看了上面各位的說明
所以寫了一隻class
1
2
3
4
5
6
7
public class UUCOM {
  static{
    System.loadLibrary("UCCom");
  }
  
  public native String GetCode(String server,String param);
}


然後再jsp 要去用它
1
2
3
4
5
<%
String strCommand="&b=2&g=3";
UUCOM uc=new UUCOM();
uc.GetCode("127.0.0.1",strCommand);
%>

可以new class 起來
但是在呼叫 GetCode() 的時候就會有問題
但是目前asp是可以正常運作的

我現在的疑問是
1.我的class 有沒有寫錯
loadLibrary("UCCom") ?? or loadLibrary("UCCom.UCQuery")??

2. method 的用法對不對??

感謝各位大大


reply to postreply to post
作者 Re:請問JNI運用在JAVA 與 c++該如何作DLL檔? [Re:bgyeats]
Duncan

還隱隱作痛

版主

發文: 7816
積分: 39
於 2006-08-03 20:01 user profilesend a private message to usersend email to Duncanreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
bgyeats wrote:
我現在的疑問是
1.我的class 有沒有寫錯
loadLibrary("UCCom") ?? or loadLibrary("UCCom.UCQuery")??

2. method 的用法對不對??

感謝各位大大


UCCom.dll 是某 COM 元件的實做,並不是包 JNI native function,不是你那樣寫就可以用。

你必須寫一個 DLL 放 native method 的實做部分,在 native method 裡透過 UCCom.dll 建立 COM 元件來用。

但我認為你可以考慮使用 Jacob 來使用 COM object,這樣你就不需要自己用 C/C++ 去寫 JNI function 製 DLL(由 Jacob 做掉)。


Duncan edited on 2006-08-03 21:00
reply to postreply to post

給我
辣味豆腐 其餘免談
作者 Re:請問JNI運用在JAVA 與 c++該如何作DLL檔? [Re:vincentwei]
bgyeats





發文: 197
積分: 0
於 2006-08-04 08:18 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
感謝 Duncan 大大
我去研究一下 Jacob


reply to postreply to post
作者 Re:請問JNI運用在JAVA 與 c++該如何作DLL檔? [Re:newworld]
mawmawmaw





發文: 42
積分: 0
於 2006-10-02 01:20 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
請問一下
我在執行最後一個動作時(java xxxx)
出現了下列錯誤
請問我少做什麼嗎



reply to postreply to post
作者 Re:請問JNI運用在JAVA 與 c++該如何作DLL檔? [Re:mawmawmaw]
Duncan

還隱隱作痛

版主

發文: 7816
積分: 39
於 2006-10-02 02:09 user profilesend a private message to usersend email to Duncanreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
mawmawmaw wrote:
請問一下
我在執行最後一個動作時(java xxxx)
出現了下列錯誤
請問我少做什麼嗎



錯誤訊息已提到:依照 java.library.path 指定的目錄裡找不到 hello 檔案。

在執行 java.exe 前先設定環境變數 PATH 使其包含你的 dll 檔案所在的"目錄"(檔案夾);或是在執行 java.exe 時指明 java.library.path property。

1
java -Djava.library.path=%The_Directory_Contains_hello.dll% test_call_c


reply to postreply to post

給我
辣味豆腐 其餘免談
作者 Re:請問JNI運用在JAVA 與 c++該如何作DLL檔? [Re:vincentwei]
mawmawmaw





發文: 42
積分: 0
於 2006-10-03 14:39 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
搭個順風車

我在製作header檔時出現了一些問題
我有把class檔所在的folde加入path
但是還是一樣
請問要如何解決



reply to postreply to post
作者 Re:請問JNI運用在JAVA 與 c++該如何作DLL檔? [Re:mawmawmaw]
Duncan

還隱隱作痛

版主

發文: 7816
積分: 39
於 2006-10-03 15:23 user profilesend a private message to usersend email to Duncanreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
mawmawmaw wrote:
搭個順風車

我在製作header檔時出現了一些問題
我有把class檔所在的folde加入path
但是還是一樣
請問要如何解決


請設定好 classpath 環境變數,或是在執行 javah.exe 時以 -classpath option 指明。


reply to postreply to post

給我
辣味豆腐 其餘免談
作者 Re:請問JNI運用在JAVA 與 c++該如何作DLL檔? [Re:Duncan]
mawmawmaw





發文: 42
積分: 0
於 2006-10-04 09:35 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
Duncan wrote:
請設定好 classpath 環境變數,或是在執行 javah.exe 時以 -classpath option 指明。

原來是要在administrator的使用者變數設classpath才會成功
設在系統變數的classpath會一樣的結果
多謝Duncan大大


reply to postreply to post
作者 Re:請問JNI運用在JAVA 與 c++該如何作DLL檔? [Re:vincentwei]
mawmawmaw





發文: 42
積分: 0
於 2007-02-01 11:54 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
請問一下
如果現在我要呼叫的 C++ code function 如下:
int j_call_c::test(){...}

那在 java 的部份應該如何寫
才可呼叫到 test()


reply to postreply to post
作者 Re:請問JNI運用在JAVA 與 c++該如何作DLL檔? [Re:Duncan]
echung





發文: 14
積分: 0
於 2007-06-06 16:52 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
Duncan wrote:
若是沒有給 import library,你得用 win32 的 LoadLibrary 去打開 dll,然後以 GetProcAddress 取得函式在 dll 裡的位置,透過 function pointer 來 invoke 此函式。


我參考藍色小舖裡的程式碼想去打開dll,但vc++回應如下的錯誤!
請問是我少include了什麼嗎?謝謝!


1>.\WordWriter.cpp(30) : error C2065: 'HINSTANCE' : 未宣告的識別項
1>.\WordWriter.cpp(30) : error C2146: 語法錯誤 : 遺漏 ';' (在識別項 'dllInstance' 之前)
1>.\WordWriter.cpp(30) : error C2065: 'dllInstance' : 未宣告的識別項
1>.\WordWriter.cpp(30) : error C3861: 'LoadLibrary': 找不到識別項


程式碼如下:(裡頭中文字串處理是引用duncan撰寫,因為沒有寫過c++所以整段是到處拚湊出來的,如有錯誤煩請指教)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <jni.h>
 
#include <stdafx.h>
 
#include "WordWriter.h"
 
#include <WordServiceImpl.h>
 
JNIEXPORT jboolean JNICALL 
Java_WordServiceImpl_OpenDocFile (JNIEnv *env, jobject jobj, jstring fileName){
  jboolean rs = false;
  jclass klass = env->GetObjectClass(fileName);
  jmethodID getBytes = env->GetMethodID(klass, "getBytes", "(Ljava/lang/String;)[B");
  jvalue arg;
  arg.l = env->NewStringUTF("Big5");
  jbyteArray chs = (jbyteArray) env->CallObjectMethodA(fileName, getBytes, &arg);
  int len = env->GetArrayLength(chs);
  jbyte* msgP = env->GetByteArrayElements(chs, 0);
  char* buf = new char[len + 1];
  buf[len] = '\0';
  for (int i = 0; i < len; ++i)
    buf[i] = msgP[i];
  env->ReleaseByteArrayElements(chs, msgP, JNI_ABORT);
  printf("Message is: %s\n", buf);  
 
  HINSTANCE dllInstance = LoadLibrary("WordCall.dll");
  (FARPROC &)OpenDocFile = GetProcAddress( dllInstance,"OpenDocFile");
  rs = OpenDocFile(buf);
  delete[] buf; 
  return false;
}


reply to postreply to post
作者 Re:請問JNI運用在JAVA 與 c++該如何作DLL檔? [Re:echung]
opq123520





發文: 3
積分: 0
於 2008-07-06 00:41 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
完成這些前置動作之後,再來將我們剛剛產生的HelloWorld.h加入我們的Header Files中,並新增一個.c的檔案HelloWorldImp.c,然後到上方的功能表中Build選則'Build hello.dll',然後你將會得到一個hello.dll在專案目錄下的Debug\hello.dll,到此為止,如果順利你應該的到dll檔

上述只說到if 但是小弟我發生了else

這段小弟我有個問題

HelloWorld.h加入我們的Header Files中 這個步驟能說清楚一點嗎?

找不到Header Files 也不知道要怎樣把HelloWorld.h加入我們的Header Files中

因為專題需要把java跟c互通 也剛剛開始學習jni

程式還處於很嫩的階段 麻煩各位大大指導小弟學習一下

※hello.dll - 3 errorMoon, 2 warningMoon


opq123520 edited on 2008-07-06 00:44
reply to postreply to post
» JWorld@TW »  Java SE 討論區

reply to topicthreaded modego to previous topicgo to next topic
  已讀文章
  新的文章
  被刪除的文章
Jump to the top of page

JWorld@TW 本站商標資訊

Powered by Powerful JuteForum® Version Jute 1.5.8