我爲C++ BSD套接字客戶端運行基本的Java包裝。我可以編譯Java並生成一個頭文件,但是當我嘗試運行它時,它會返回Exception in thread "main" java.lang.UnsatisfiedLinkError: JavaClient.socketComm()V
本地方法上的JNI UnsatisfiedLinkError
從我所能找到的內容看來,這似乎表示方法簽名之間不匹配,但我找不到任何錯誤。
Java代碼的
public class JavaClient
{
public native void socketComm();
public static void main(String[] args)
{
System.load("/home/cougar/workspace/ArbiterBSDSocketComms/JNIClient/JavaClient.so");
JavaClient client = new JavaClient();
client.socketComm();
System.out.println("Done");
}
}
C實現
#include <iostream>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
#include <errno.h>
#include <cstdlib>
#include <stdio.h>
#include <jni.h>
#include "JavaClient.h"
#define MAXHOSTNAME 256
JNIEXPORT void JNICALL Java_JavaClient_socketComm
(JNIEnv *env, jobject obj) {
struct sockaddr_in remoteSocketInfo;
struct hostent *hPtr;
int socketHandle;
char *remoteHost="localhost";
int portNumber = 8080;
memset(&remoteSocketInfo, 0, sizeof(struct sockaddr_in)); //Clear structure memory
if ((hPtr = gethostbyname(remoteHost)) == NULL) //Get sysinfo
{
printf("System DNS resolution misconfigured.");
printf("Error number: ", ECONNREFUSED);
exit(EXIT_FAILURE);
}
if((socketHandle = socket(AF_INET, SOCK_STREAM, 0)) < 0) //Create socket
{
close(socketHandle);
exit(EXIT_FAILURE);
}
memcpy((char *)&remoteSocketInfo.sin_addr,
hPtr->h_addr, hPtr->h_length); //Load sys info into sock data structures
remoteSocketInfo.sin_family = AF_INET;
remoteSocketInfo.sin_port = htons((u_short)portNumber); //Set port number
if(connect(socketHandle, (struct sockaddr *)&remoteSocketInfo, sizeof(struct sockaddr_in)) < 0)
{
close(socketHandle);
exit(EXIT_FAILURE);
}
int rc=0;
char buf[512];
strcpy(buf, "Sup server");
send(socketHandle, buf, strlen(buf)+1, 0);
}
void main(){}
頭文件
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class JavaClient */
#ifndef _Included_JavaClient
#define _Included_JavaClient
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: JavaClient
* Method: socketComm
* Signature:()V
*/
JNIEXPORT void JNICALL Java_JavaClient_socketComm
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
藉口一些不好的格式,我沒有用太多計算器和代碼格式化有點粗略。
這些文件都位於/ JNIClient中。
我正在運行Ubuntu 12.04 x64,並且我安裝了32位和64位JDK。我試圖用32位版本生成.so,這本來是理想的,但我得到了一個ELF不匹配,所以我只用64位,所以我不必處理這個問題。 (。上任何見解是值得歡迎的爲好)
我的過程是:
$>javac JavaClient.java
$>javah JavaClient
$>cc -m64 -g -I/usr/lib/jvm/java-6-openjdk-amd64/include -I/usr/lib/jvm/java-6-openjdk-amd64/include/linux -shared JavaClient.c -o JavaClient.so
$>java JavaClient
完整的錯誤消息是
個Exception in thread "main" java.lang.UnsatisfiedLinkError: JavaClient.socketComm()V
at JavaClient.socketComm(Native Method)
at JavaClient.main(JavaClient.java:9)
$>nm JavaClient.so
回報:
[email protected]:~/workspace/ArbiterBSDSocketComms/JNIClient$ nm JavaClient.so
0000000000200e50 a _DYNAMIC
0000000000200fe8 a _GLOBAL_OFFSET_TABLE_
w _Jv_RegisterClasses
0000000000200e30 d __CTOR_END__
0000000000200e28 d __CTOR_LIST__
0000000000200e40 d __DTOR_END__
0000000000200e38 d __DTOR_LIST__
00000000000005e0 r __FRAME_END__
0000000000200e48 d __JCR_END__
0000000000200e48 d __JCR_LIST__
0000000000201010 A __bss_start
w [email protected]@GLIBC_2.2.5
0000000000000540 t __do_global_ctors_aux
0000000000000490 t __do_global_dtors_aux
0000000000201008 d __dso_handle
w __gmon_start__
0000000000201010 A _edata
0000000000201020 A _end
0000000000000578 T _fini
0000000000000438 T _init
0000000000000470 t call_gmon_start
0000000000201010 b completed.6531
0000000000201018 b dtor_idx.6533
0000000000000510 t frame_dummy
編輯:我有一個理論,即。所以正在興建不當,如$>nm JavaClient.so
不顯示在它的方法名。有關cc命令有什麼問題的任何建議?
好吧,SO:我一直在這,因爲沒有什麼看起來不錯。方法簽名全部匹配,沒有什麼應該是錯誤的,eclipse文件屬性表示它正在編輯正確的文件等等等等。我終於捕獲了JavaClient.c,並且它是空白的。顯然,eclipse並非真正編輯它所說的文件。修正了,現在一切都很好。
郵政'nm'輸出 – 2012-07-16 21:21:03
NM輸出增加,你可以看到有一個在。所以到socketComm沒有提及。我不知道爲什麼 – 2012-07-16 21:26:21
請不要將標題改爲[已解決]。相反,直接回答你的問題,然後接受你的答案。這使得未來的訪問者更容易找到你的問題的答案。 – templatetypedef 2012-07-16 22:59:41