我使用JNA(Java Native Access)从Java调用本机方法到C。本机方法(int funcServer(int param1))是一个基本的unix套接字侦听。但不管我是否做了优化的JNA
Direct Mapping
或
Interface Mapping
,JNA在我身上熄火了。本地代码即使在函数调用的第一行也不会打印任何内容,但没有抛出异常。
参见我的最低可行Java示例(在NetBeans IDE产品版本:8.0.2 Build 201411181905和Ubuntu Linux上运行):
package viableexamplejava;
import com.sun.jna.*;
public class ViableExample {
public interface NativeLibary extends Library {
public int funcServer(int param1);
}
public static native int funcServer(int param1);
static {
final String windowsLibraryName = "ViableExample.dll";
final String linuxLibraryName = "libViableExampleNative.so";
if (Platform.isWindows()) {
System.err.println("Loading Windows dll. 'cygwin1.dll' should be in same directory.");
Native.register(windowsLibraryName);
} else {
System.err.println("Loading Linux .so");
Native.register(linuxLibraryName);
}
}
public static void main(String[] args) {
System.err.println("Hello World from Java");
funcServer(7);
}
}
这是我使用的C代码:
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>
int funcServer(int param1) {
printf("\n Hello World from C. This is a Socket Server Example Program \n");
printf("\n param1: %d \n", param1);
{
int listenfd = 0, connfd = 0;
struct sockaddr_in serv_addr;
char sendBuff[1025];
time_t ticks;
printf("I made it to line %d in file %s\n", __LINE__, __FILE__);
listenfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&serv_addr, '0', sizeof (serv_addr));
memset(sendBuff, '0', sizeof (sendBuff));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(5000);
bind(listenfd, (struct sockaddr*) &serv_addr, sizeof (serv_addr));
printf("I made it to line %d in file %s\n", __LINE__, __FILE__);
listen(listenfd, 10);
while (1) {
connfd = accept(listenfd, (struct sockaddr*) NULL, NULL);
ticks = time(NULL);
snprintf(sendBuff, sizeof (sendBuff), "%.24s\r\n", ctime(&ticks));
write(connfd, sendBuff, strlen(sendBuff));
close(connfd);
sleep(1);
}
}
return 0;
}
更新1
尝试将.so放入jar文件,然后从终端运行它(UnsatisfiedLinkError:无法加载库“libViableExampleNative.so”:无法获取linux-x86-64/libViableExaampleNative.s0的InputStream):
$ zip ./ViableExampleJava.jar ./libViableExampleNative.so
adding: libViableExampleNative.so (deflated 73%)
~/NetBeansProjects/ViableExampleJava/dist$ java -jar ./ViableExampleJava.jar
Loading Linux .so
Exception in thread "main" java.lang.UnsatisfiedLinkError: Unable to load library 'libViableExampleNative.so': Can't obtain InputStream for linux-x86-64/libViableExampleNative.so
at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:271)
at com.sun.jna.NativeLibrary.getInstance(NativeLibrary.java:398)
at com.sun.jna.Native.register(Native.java:1396)
at com.sun.jna.Native.register(Native.java:1156)
at viableexamplejava.ViableExample.<clinit>(ViableExample.java:33)
*更新2*
尝试设置系统属性“jna.library.path”
从终端(而不是Netbeans)运行时的正确输出:
// Set jnaPath to: /home/user/NetBeansProjects/ViableExampleNative/dist/Debug/GNU-Linux-x86
$ java -jar ./ViableExampleJava.jar
Hello World from Java
Hello World from C. This is a Socket Server Example Program
param1: 7
I made it to line 26 in file ../../Desktop/Dropbox/ViableExample/native/ViableExample.c
I made it to line 37 in file ../../Desktop/Dropbox/ViableExample/native/ViableExample.c
*更新3*
尽管它在Ubuntu Linux终端上运行,但我的Windows版本(使用Cygwin)失败了。