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 call C++ 的問題
CharArray





發文: 54
積分: 0
於 2008-10-07 19:19 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
1
2
3
4
5
6
7
8
9
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT void JNICALL Java_Hello_hello
  (JNIEnv *, jobject, jstring);
 
#ifdef __cplusplus
}
#endif

這是我用javah編譯出來的Hello.h

我想問2個問題

1. 我在網路上查到extern "C"的原因是C的function name的存法跟C++
所以要指示compiler要用C的方式編譯function
但是我用的是Visual Studio C++ 存檔也是存成.cpp 為什麼
還是可以正常執行呢?

2. JNIEXPORT void JNICALL Java_Hello_hello
這行function signature為什麼可以通過C++ compiler的編譯?
JNIEXPORT跟JNICALL為什麼可以寫在那個地方??

抱歉 問的都是C++的問題 如果不適合在這問 可以請版主把這篇移到適合的地方(or delete)


CharArray edited on 2008-10-07 19:31
reply to postreply to post
作者 Re:JNI java call C++ 的問題 [Re:CharArray]
aloneworker





發文: 13
積分: 0
於 2008-10-07 19: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
這只是一種語法
如果你寫過MFC 你就會發現 其實很多不算正規的語法(因該說書上沒寫的...)
都會因為這樣出現的
想MFC中的 afx void .... 或 BEGIN_MESSAGE_MAP(A, CDialog) ( 後面沒有分號)
這類語法是因為特殊要求 而加上去的
一般不太需要 在意他 而他也沒啥麼大的哲理
只是讓編譯器知道他是幹神麼的就行了.....


reply to postreply to post
作者 Re:JNI java call C++ 的問題 [Re:CharArray]
Duncan

還隱隱作痛

版主

發文: 7816
積分: 39
於 2008-10-07 19:46 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
CharArray wrote:
1
2
3
4
5
6
7
8
9
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT void JNICALL Java_Hello_hello
  (JNIEnv *, jobject, jstring);
 
#ifdef __cplusplus
}
#endif

這是我用javah編譯出來的Hello.h

我想問2個問題

1. 我在網路上查到extern "C"的原因是C的function name的存法跟C++
所以要指示compiler要用C的方式編譯function
但是我用的是Visual Studio C++ 存檔也是存成.cpp 為什麼
還是可以正常執行呢?

2. JNIEXPORT void JNICALL Java_Hello_hello
這行function signature為什麼可以通過C++ compiler的編譯?
JNIEXPORT跟JNICALL為什麼可以寫在那個地方??

抱歉 問的都是C++的問題 如果不適合在這問 可以請版主把這篇移到適合的地方(or delete)


1. 使用 C++ compiler 時,在編譯時會有 __cplusplus 這個 predefined symbol。javah 產生的 header 中的寫法作用是當你使用的 C++ compiler 時,就把 function prototype 包在 extern "C" {...} 裡,用來告訴 C++ 編譯器在編譯該 function 時不要使用 C++ 的命名規則來輸出該 function。(否則 JVM 在載入你的 dll 後會找不到該 function)

2. JNIEXPORT 與 JNICALL 會被 preprocessor 替換成其他的字串,請參閱此二 MACRO 在 %JDK_DIR%\include\win32\jni_md.h 中的定義。


reply to postreply to post

給我
辣味豆腐 其餘免談
作者 Re:JNI java call C++ 的問題 [Re:Duncan]
CharArray





發文: 54
積分: 0
於 2008-10-07 20:31 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:
extern "C" {...} 裡,用來告訴 C++ 編譯器在編譯該 function 時不要使用 C++ 的命名規則來輸出該 function。


用C的命名規則輸出,這是不是代表native function不支援function overloading ?

我測試overloading hello(String s)及hello() 可以成功做成dll

但在執行java Hello會出現UnsatisfiedLinkError 就是這個原因嗎?


CharArray edited on 2008-10-07 20:38
reply to postreply to post
作者 Re:JNI java call C++ 的問題 [Re:Duncan]
CharArray





發文: 54
積分: 0
於 2008-10-07 20:45 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:
JNIEXPORT 與 JNICALL 會被 preprocessor 替換成其他的字串,請參閱此二 MACRO 在 %JDK_DIR%\include\win32\jni_md.h 中的定義。


代換成其他字串 我的疑問還是存在的

照aloneworker版友的說法 只要讓compiler知道在幹馬就行了

但是Visual Studio C++ 跟 gnu gcc都支援這種語法

似乎每個compiler都看得懂這奇怪的語法

這本身就算正規的C++ spec語法嗎? or compiler共識之類的


CharArray edited on 2008-10-07 20:48
reply to postreply to post
作者 Re:JNI java call C++ 的問題 [Re:CharArray]
Duncan

還隱隱作痛

版主

發文: 7816
積分: 39
於 2008-10-07 22:10 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
CharArray wrote:
用C的命名規則輸出,這是不是代表native function不支援function overloading ?

我測試overloading hello(String s)及hello() 可以成功做成dll

但在執行java Hello會出現UnsatisfiedLinkError 就是這個原因嗎?


請詳述你做了什麼事。

C function 彼此不能 overload,你不能做到兩個同名的 C function 存在同一個模組。


reply to postreply to post

給我
辣味豆腐 其餘免談
作者 Re:JNI java call C++ 的問題 [Re:CharArray]
Duncan

還隱隱作痛

版主

發文: 7816
積分: 39
於 2008-10-07 22:18 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
CharArray wrote:
代換成其他字串 我的疑問還是存在的

照aloneworker版友的說法 只要讓compiler知道在幹馬就行了

但是Visual Studio C++ 跟 gnu gcc都支援這種語法

似乎每個compiler都看得懂這奇怪的語法

這本身就算正規的C++ spec語法嗎? or compiler共識之類的


你的意思是你不懂 "__declspec(dllexport)" 與 "__stdcall"?

這些 keyword 不是 standard C/C++ 所規範,是編譯器廠商擴充的 keyword。

其意義與用法請自行翻閱 VS2005 manual/documentation or MSDN(既然你使用 Visual C++)。


reply to postreply to post

給我
辣味豆腐 其餘免談
作者 Re:JNI java call C++ 的問題 [Re:Duncan]
CharArray





發文: 54
積分: 0
於 2008-10-07 22: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
Duncan wrote:
請詳述你做了什麼事。

C function 彼此不能 overload,你不能做到兩個同名的 C function 存在同一個模組。


我就是在Hello.java內宣告
1
2
private native void hello(String s);
private native void hello();


然後compile出 Hello.h 內有
1
2
3
4
5
JNIEXPORT void JNICALL Java_Hello_hello__Ljava_lang_String_2
  (JNIEnv *, jobject, jstring);
 
JNIEXPORT void JNICALL Java_Hello_hello__
  (JNIEnv *, jobject);

然後用Hello.c去實作Hello.h

compile出.DLL檔

Hello.java在呼叫
Hello.hello()時,會出現UnsatisfiedLinkError


reply to postreply to post
作者 Re:JNI java call C++ 的問題 [Re:CharArray]
Duncan

還隱隱作痛

版主

發文: 7816
積分: 39
於 2008-10-07 23:22 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
CharArray wrote:
我就是在Hello.java內宣告
1
2
private native void hello(String s);
private native void hello();


然後compile出 Hello.h 內有
1
2
3
4
5
JNIEXPORT void JNICALL Java_Hello_hello__Ljava_lang_String_2
  (JNIEnv *, jobject, jstring);
 
JNIEXPORT void JNICALL Java_Hello_hello__
  (JNIEnv *, jobject);

然後用Hello.c去實作Hello.h

compile出.DLL檔

Hello.java在呼叫
Hello.hello()時,會出現UnsatisfiedLinkError


這樣子沒有問題。Java overloaded method 對應的 JNI function 有不同的名稱。

我猜你的 Java 程式是(忘了寫)缺了載入 JNI dll library 的動作。
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/System.html#loadLibrary(java.lang.String)


Duncan edited on 2008-10-08 00:23
reply to postreply to post

給我
辣味豆腐 其餘免談
作者 Re:JNI java call C++ 的問題 [Re:Duncan]
CharArray





發文: 54
積分: 0
於 2008-10-08 17:09 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:
這樣子沒有問題。Java overloaded method 對應的 JNI function 有不同的名稱。


ok! 測試過了,果然可以,應該是我昨天手忙腳亂的試不知道弄錯了什麼。

我昨天的問題是extern "C"是指示compiler把function name用C的型態輸出

那為何這樣會 jni 會支援overloading,原來是 jni 的function name有加上parameter的資訊

現在了解了 謝謝
1
2
3
4
5
6
7
8
extern "C" {
 
JNIEXPORT void JNICALL Java_Hello_hello__Ljava_lang_String_2
 (JNIEnv *, jobject, jstring);
 
JNIEXPORT void JNICALL Java_Hello_hello__
  (JNIEnv *, jobject);
}


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