使用JNA windows系統調用kernel32.dll庫, inux系統調用libc.so庫
1. 環境
jdk1.7
windows7
centos 7
2. 依賴的jar
本程序需要依賴JNA框架.
jna.jar
3. 接口
import java.util.Date;
public interface JNative {
/**
* 設置系統時間
* @param date Date
*/
public void setLocalTime(Date date);
}
4. windows實現
import java.util.Calendar;
import java.util.Date;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Structure;
public class WindowsImpl implements JNative{
public static class SYSTEMTIME extends Structure {
public short wYear;
public short wMonth;
public short wDayOfWeek;
public short wDay;
public short wHour;
public short wMinute;
public short wSecond;
public short wMilliseconds;
}
public interface Kernel32 extends Library{
public boolean SetLocalTime(SYSTEMTIME st); //帶時區
public int GetCurrentProcessId();
}
public static Kernel32 kernel32Instance = null;
public WindowsImpl(){
kernel32Instance = (Kernel32)Native.loadLibrary("kernel32", Kernel32.class);
}
@Override
public void setLocalTime(Date date) {
Calendar c = Calendar.getInstance();
c.setTime(date);
SYSTEMTIME st = new SYSTEMTIME();
st.wYear = (short)c.get(Calendar.YEAR);
st.wMonth = (short)(c.get(Calendar.MONTH) + 1);
st.wDay = (short)c.get(Calendar.DAY_OF_MONTH );
st.wDayOfWeek = (short)c.get(Calendar.DAY_OF_WEEK);
st.wHour = (short)c.get(Calendar.HOUR_OF_DAY);
st.wMinute = (short)c.get(Calendar.MINUTE);
st.wSecond = (short)c.get(Calendar.SECOND);
st.wMilliseconds = (short)c.get(Calendar.MILLISECOND);
kernel32Instance.SetLocalTime(st);
}
}
5. linux實現
import java.util.Date;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.NativeLong;
import com.sun.jna.Structure;
public class LinuxImpl implements JNative {
public static class tm extends Structure{
public static class ByReference extends tm implements Structure.ByReference{}
public static class ByValue extends tm implements Structure.ByValue{}
public int tm_sec;//seconds 0-61
public int tm_min;//minutes 1-59
public int tm_hour;//hours 0-23
public int tm_mday;//day of the month 1-31
public int tm_mon;//months since jan 0-11
public int tm_year;//years from 1900
public int tm_wday;//days since Sunday, 0-6
public int tm_yday;//days since Jan 1, 0-365
public int tm_isdst;//Daylight Saving time indicator
}
public static class timeval extends Structure{
public static class ByReference extends timeval implements Structure.ByReference{}
public static class ByValue extends timeval implements Structure.ByValue{}
public NativeLong tv_sec; /* 秒數 */
public NativeLong tv_usec; /* 微秒數 */
}
public static class timezone extends Structure{
public static class ByReference extends timezone implements Structure.ByReference{}
public static class ByValue extends timezone implements Structure.ByValue{}
public int tz_minuteswest;
public int tz_dsttime;
}
public interface CLibrary extends Library{
int gettimeofday(timeval.ByReference tv, timezone.ByReference tz);
int settimeofday(timeval.ByReference tv, timezone.ByReference tz);
}
public static CLibrary cLibraryInstance = null;
public LinuxImpl(){
cLibraryInstance = (CLibrary)Native.loadLibrary("c", CLibrary.class);
}
@Override
public void setLocalTime(Date date) {
long ms = date.getTime();
long s = ms / 1000; //秒
long us = (ms % 1000) * 1000; //微秒
timeval.ByReference tv = new timeval.ByReference();
timezone.ByReference tz = new timezone.ByReference();
cLibraryInstance.gettimeofday(tv, tz);
tv.tv_sec = new NativeLong(s);
tv.tv_usec = new NativeLong(us);
cLibraryInstance.settimeofday(tv, tz);
}
}
6. 工廠類
import com.sun.jna.Platform;
public class NativeFactory {
public static JNative newNative(){
if(Platform.isWindows()){
return new WindowsImpl();
}
return new LinuxImpl();
}
}
注意新的Structure 要求實現 getFielOrder 方法,只需將結構內的字段名稱 以字符串list的方式返回即可。