去年也大概是這個時候寫了第一個Java2EXE,之后又加了寫特性,但是每次我看代碼都感覺慘不忍睹,很混亂,而且編譯,鏈接的過程也有點繞。
現在又過了一年了,如果說上次版本的Load過程主要是靠Java(Java加密,解壓),那么這次基本把這些費時的操作全交給CPP了。
好了,總結一下這次的改動
1)Loader以及Starter完全是CPP代碼,結構很清晰了。
2)加密以及解壓交給CPP,速度比以前快了。
3)整合了
JNative,這個是重點,下文詳述。
4)生成工具用MFC寫,一個簡單的向導。
OK,那么JNative是干什么的呢?
官方的描述是 “
JNative, Java framework for DLL access for Windows and Linux”
就是說,有了這個框架,你訪問DLL里的方法就不再需要寫DLL了,只需要寫Java Code了,可能有人問它是怎么做到的呢?
假如說你要訪問Kernel32.dll里的某個方法A,你首先需要這個方法的句柄,這個句柄就是通過new一個org.xvolks.jnative.JNative實例來保持的,
類似如:
org.xvolks.jnative.Native methodA=new org.xvolks.jnative.JNative("Kernel32.dll","A");
有了這個句柄,你只要在上面設置參數,返回值,以及類型就可以調用它了。每個調用它上面的JNI里的本地方法就會自動來進行參數解析,解碼,調用到目標DLL方法,這個過程基本不可避免需要少量的匯編代碼。
JNative為了可移植性,代碼是在Cygwin下可編譯的,沒有MSVC可編譯的版本。
對此,本人改了部分代碼用于直接一起鏈接(主要是把GCC嵌入匯編改為對應的MSVC的嵌入匯編代碼),而不是讓JNative生成一個動態鏈接庫。
如上,由于JNative改成了靜態庫,程序發布的時候,只要是通過Java2EXE Builder來創建成EXE的話,你就不需要那個JNativeCpp.dll文件了,只有一個EXE.
你調試的時候可以用官方的版本,發布就只要你的代碼(JNative的class也都在集成在生成工具里,不需要你自己添加進來)。
來看個簡單的例子,我們從Java代碼里取得當前進程的全路徑名:
import org.xvolks.jnative.JNative;
import org.xvolks.jnative.Type;
import org.xvolks.jnative.exceptions.NativeException;
import org.xvolks.jnative.pointers.Pointer;
import org.xvolks.jnative.pointers.memory.HeapMemoryBlock;
/**
* DWORD GetModuleFileName(
* HMODULE hModule,
* LPTSTR lpFilename,
* DWORD nSize
*);
* @author yovn
*
*/
public class TestReadProcessPath {
/**
*
* @param args
* @throws NativeException
* @throws IllegalAccessException
*/
public static void main(String[] args) throws NativeException, IllegalAccessException {
JNative v=new JNative("Kernel32.dll","GetModuleFileNameA");
int i = 0;
v.setRetVal(Type.INT);
Pointer pName = new Pointer(new HeapMemoryBlock(1024));
v.setParameter(i++, 0);//module handle
v.setParameter(i++, pName);//pFileName
v.setParameter(i++, 1024);//nSize
v.setRetVal(Type.INT);
v.invoke();
int ret = Integer.parseInt(v.getRetVal());
if (ret == 0) {
// return "null";
System.err.println(
"GetModuleFileName failed!");
} else {
String path = pName.getAsString().substring(0,
ret);
pName.dispose();
v.dispose();
System.out.println("current process's path is:"+path);
}
}
}
編譯,把這個文件單獨打包成一個jar文件,下面是個用這個工具生成EXE的截圖:
生成EXE向導第一步
生成 EXE向導第二步
請從這里下載
Java2EXE Builder Platform