本机方法上的JNI UnsatifiedLinkError 我为C++的BSD套接字客户端运行了一个基本的java包装器。我可以编译Java并生成头文件,但当我尝试运行它时,它在线程“main”Java.lang.UnsatisfiedLinkError:JavaClient.socketComm()V
根据我所能找到的,这似乎表明方法签名之间存在不匹配,但我找不到我的签名有任何错误 Java代码本机方法上的JNI UnsatifiedLinkError 我为C++的BSD套接字客户端运行了一个基本的java包装器。我可以编译Java并生成头文件,但当我尝试运行它时,它在线程“main”Java.lang.UnsatisfiedLinkError:JavaClient.socketComm()V,java,c++,c,java-native-interface,Java,C++,C,Java Native Interface,根据我所能找到的,这似乎表明方法签名之间存在不匹配,但我找不到我的签名有任何错误 Java代码 public class JavaClient { public native void socketComm(); public static void main(String[] args) { System.load("/home/cougar/workspace/ArbiterBSDSocketComms/JNIClient/JavaClient.s
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(){}
$>nm JavaClient。因此
返回:
cougar@Wanda:~/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 __cxa_finalize@@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
编辑:我有一个理论认为.so的构建不正确,因为$>nm JavaClient.so
没有显示其中的方法名。关于cc命令的错误有什么建议吗
好吧,所以:我一直这么说,因为似乎没有什么是对的。方法签名都是匹配的,没有任何错误,eclipse文件属性说它正在编辑正确的文件,等等。我最终找到了JavaClient.c,它是空白的。显然eclipse并没有实际编辑它所说的文件。解决了这个问题,现在一切都好了。我会给你一个更好的解决方案
public void socketComm() throws IOException
{
Socket socket = new Socket("localhost", 8080);
try
{
socket.getOutputStream().write("Sup server\u0000".getBytes());
}
finally
{
socket.close(); // You forgot this
}
}
根本不需要JNI。与您的代码不同,如果socket()返回<0,它也不会关闭无效的句柄。我一直这么说,因为似乎没有什么是正确的。方法签名都是匹配的,没有任何错误,eclipse文件属性说它正在编辑正确的文件,等等。我最终找到了JavaClient.c,它是空白的。显然eclipse并没有实际编辑它所说的文件。修好了,现在一切都好了
我不知道为什么Eclipse声称正在编辑一个空白文件,我检查了又检查,它没有引用任何链接或任何东西,但如果您遇到与我相同的问题,请检查它。NM输出添加,正如您可以看到的那样。so中没有引用socketComm。我不知道为什么请不要将标题更改为[已解决]。相反,直接回答你的问题,然后接受你的答案。这使得未来的访问者更容易找到问题的答案。我的坏习惯,仍然习惯于这样的礼仪,我知道我可以处理爪哇的套接字:)这将和一个完全用C++编写的其他软件一起使用,我们希望用一个类来处理套接字,而不是用C++和java中的一个。
cougar@Wanda:~/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 __cxa_finalize@@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
public void socketComm() throws IOException
{
Socket socket = new Socket("localhost", 8080);
try
{
socket.getOutputStream().write("Sup server\u0000".getBytes());
}
finally
{
socket.close(); // You forgot this
}
}