⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jnative.java

📁 jnative java 调用动态库需要的包和dll
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
package org.xvolks.jnative;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
import java.util.Vector;
import java.util.WeakHashMap;

import org.xvolks.jnative.exceptions.NativeException;
import org.xvolks.jnative.logging.ConsoleLogger;
import org.xvolks.jnative.logging.JNativeLogger;
import org.xvolks.jnative.logging.JNativeLogger.SEVERITY;
import org.xvolks.jnative.misc.SecurityAttributes;
import org.xvolks.jnative.misc.basicStructures.DWORD;
import org.xvolks.jnative.misc.basicStructures.HANDLE;
import org.xvolks.jnative.misc.basicStructures.HWND;
import org.xvolks.jnative.misc.basicStructures.LONG;
import org.xvolks.jnative.pointers.NullPointer;
import org.xvolks.jnative.pointers.Pointer;
import org.xvolks.jnative.pointers.memory.NativeMemoryBlock;
import org.xvolks.jnative.util.Callback;
import org.xvolks.jnative.util.DbgHelp;
import org.xvolks.jnative.util.Kernel32;
import org.xvolks.jnative.util.StructConverter;
import org.xvolks.jnative.util.WindowProc;

//import com.sun.org.apache.xerces.internal.impl.xpath.regex.ParseException;

/**
 * JNative this is the main class for calling native functions.<br>
 * 
 * $Id: JNative.java,v 1.36 2007/05/07 17:31:11 mdenty Exp $; <br>
 * To do so you have to :
 * <ul>
 * <li>create a new JNative object (JNative messageBox = new
 * JNative("User32.dll", "MessageBoxA");</li>
 * <li>set its return type (messageBox.setRetVal(Type.INT);</li>
 * <li>pass some parameters (messageBox.setParameter(0, Type.INT, "0");</li>
 * <li>pass some parameters (messageBox.setParameter(1, Type.STRING,
 * "message");</li>
 * <li>pass some parameters (messageBox.setParameter(2, Type.STRING,
 * "caption");</li>
 * <li>pass some parameters (messageBox.setParameter(3, Type.INT, "" + 0);</li>
 * <li>then invoke the function (messageBox.invoke();</li>
 * <li>you can get its return value (messageBox.getRetVal();</li>
 * <li>dispose native resources when they no more needed (messageBox.dispose();</li>
 * </ul>
 * So simple :) <br>
 * if you have to deal with pointers you can create some, here is a sample, it
 * uses one pointer but could have be done with 3 (one per PULARGE_INTEGER)
 * <hr>
 * The C function to call
 * 
 * <pre>
 * BOOL GetDiskFreeSpaceEx(LPCTSTR lpDirectoryName,
 * 		PULARGE_INTEGER lpFreeBytesAvailable,
 * 		PULARGE_INTEGER lpTotalNumberOfBytes,
 * 		PULARGE_INTEGER lpTotalNumberOfFreeBytes);
 * 
 * </pre>
 * 
 * <HR>
 * The implementation in Java with JNative
 * 
 * <pre>
 * public static final FreeDiskSpace getDiskFreeSpaceEx(String drive)
 * 		throws NativeException, IllegalAccessException {
 * 	if (drive == null)
 * 		throw new NullPointerException(&quot;The drive name cannot be null !&quot;);
 * 	Pointer lpFreeBytesAvailable = new Pointer(24);
 * 	int i = 0;
 * 	JNative fs = new JNative(&quot;Kernel32.dll&quot;, &quot;GetDiskFreeSpaceExA&quot;);
 * 	fs.setRetVal(Type.INT);
 * 	fs.setParameter(i++, Type.STRING, drive);
 * 	fs.setParameter(i++, lpFreeBytesAvailable.getPointer(), 8);
 * 	fs.setParameter(i++, lpFreeBytesAvailable.getPointer() + 8, 8);
 * 	fs.setParameter(i++, lpFreeBytesAvailable.getPointer() + 16, 8);
 * 	fs.invoke();
 * 	FreeDiskSpace dsp = new FreeDiskSpace(drive, lpFreeBytesAvailable);
 * 	lpFreeBytesAvailable.dispose();
 * 	return dsp;
 * }
 * </pre>
 * 
 * <HR>
 * $Id: JNative.java,v 1.36 2007/05/07 17:31:11 mdenty Exp $
 * 
 * This software is released under the LGPL.
 * 
 * @author Created by Marc DENTY - (c) 2006 JNative project
 */

public class JNative {
	
	public static class LibDesc {
		int handle;
		String libName;
		int numHolders;
		
		@Override
		public String toString() {
			return String.format("Lib info (name = %s, handle = %x, inUseFor = %d)", libName, handle, numHolders);
		}
	}
	
	private final static Map<String, LibDesc> mLibs;
	
	public static LibDesc getLibDesc(String name) {
		synchronized (mLibs) {
			LibDesc libDesc = mLibs.get(name);
			if(libDesc == null) {
				libDesc = new LibDesc();
				libDesc.libName = name;
				mLibs.put(name, libDesc);
			}
			return libDesc;		
		}
	}
	
	/**
	 * Pointer on the function address
	 */
	private final int mJNativePointer;
	

	@SuppressWarnings("unused")
	// Used by native side (handle of the library)
	private int mJNativeHModule;
	
	// Used by native side
	private int convention;

	private boolean isClosed = false;

	private final String mDllName;

	private final String mFunctionName;

	private static Map<Integer, Callback> callbacks = new TreeMap<Integer, Callback>();

	/*
	 * The five following fields are used by native side directly !
	 */
	/**
	 * Pre-allocated parameter array, need to grow if needed
	 */
	private Vector<byte[]> parameters = new Vector<byte[]>();

	private Vector<Integer> parameterTypes = new Vector<Integer>();

	private String mRetValue;

	@SuppressWarnings("unused")
	private int mRetType;

	@SuppressWarnings("unused")
	private Vector<byte[]> getParameters() {
		return parameters;
	}

	@SuppressWarnings("unused")
	private Vector<Integer> getParameterTypes() {
		return parameterTypes;
	}

	
	public static int callback(int address, long[] values) {
		//if(DEBUG)
            getLogger().log(SEVERITY.DEBUG, String.format("in Java callback #%x with %d arguments\n", address, values.length));
		return callbacks.get(address).callback(values);
	}

	@Override
	public String toString() {
		return mDllName + "-" + mFunctionName;
	}

	private native int nLoadLibrary(String dllName, String funcPointer,
			boolean debug) throws NativeException;
	private native int nFindFunction(int libHandle, String funcPointer,
			boolean debug) throws NativeException;

	// private native void nSetParameter(int jNativePointer, int pos, String
	// type,
	// byte[] value) throws NativeException;

//	private native void nSetPointer(int jNativePointer, int pos, int pointer,
//			int size) throws NativeException;
//
	private native String nGetParameter(int jNativePointer, int pos)
			throws NativeException;

	private native void nInvoke(int jNativePointer) throws NativeException;

	private native void nDispose(int jNativePointer) throws NativeException;

	private static native int nMalloc(int size) throws NativeException;

	private static native void nFree(int pointer) throws NativeException;

	private static native void nSetMemory(int pointer, byte[] buff, int offset,
			int len) throws NativeException;

	private static native byte[] nGetMemory(int pointer, int len)
			throws NativeException;

	private static native int nRegisterWindowProc(int hwnd, Object winProc,
			boolean custom) throws NativeException;

	private static native int nGetCurrentModule() throws NativeException;

	private static native int nCreateCallBack(int numParams)
			throws NativeException;

	private static native boolean nReleaseCallBack(int pos)
			throws NativeException;

	private static native int nGetNativePattern(int jNativePointer,
			byte[] pattern, int maxLen) throws NativeException;

	private static native String nGetNativeSideVersion() throws NativeException;

	
	public static void setDefaultCallingConvention(Convention defaultConvention) {
		Convention.setDefaultStyle(defaultConvention);
	}
	
	
	/**
	 * Creates a function without debug output that can call an anonymous function by it's address
	 * 	 * @exception NativeException
	 *                if the dll was not found, function name is incorrect...
	 */
	public JNative(int address, Convention convention) throws NativeException {
		if (!initDone) {
			throw new IllegalStateException(
					"JNative library not loaded, sorry !");
		}
		this.convention = convention.getValue();
		mDllName = "Anonymous";
		mFunctionName = mDllName;
		mJNativePointer = address;
		try {
			setRetVal(Type.VOID);
		} catch (IllegalAccessException e) {
			getLogger().log(SEVERITY.ERROR, e);
		}        
	}

	/**
	 * Constructor exact call of new JNative(dllName, functionName, false, Convention.DEFAULT); <br>
	 * Creates a function without debug output
	 * 
	 * @param dllName
	 *            the name of library file
	 * @param functionName
	 *            the decorated name of the function (MessageBoxA instead of
	 *            MessageBox)
	 * 
	 * @exception NativeException
	 *                if the dll was not found, function name is incorrect...
	 * @see org.xvolks.jnative.JNative#getDLLFileExports(String)
	 */
	public JNative(String dllName, String functionName) throws NativeException {
		this(dllName, functionName, false, Convention.DEFAULT);
	}

	/**
	 * Constructor exact call of new JNative(dllName, functionName, false, convention); <br>
	 * Creates a function without debug output
	 * 
	 * @param dllName
	 *            the name of library file
	 * @param functionName
	 *            the decorated name of the function (MessageBoxA instead of
	 *            MessageBox)
	 * @param convention 
	 * 			  convention of function call          
	 *  
	 * 
	 * @exception NativeException
	 *                if the dll was not found, function name is incorrect...
	 * @see org.xvolks.jnative.JNative#getDLLFileExports(String)
	 */
	public JNative(String dllName, String functionName, Convention convention) throws NativeException {
		this(dllName, functionName, false, convention);
	}
	
	/**
	 * Constructor exact call of new JNative(dllName, functionName, debug, Convention.DEFAULT); <br>
	 * Creates a function without debug output
	 * 
	 * @param dllName
	 *            the name of library file
	 * @param functionName
	 *            the decorated name of the function (MessageBoxA instead of
	 *            MessageBox)
	 * @param nativeDebug
	 *            a boolean if true the dll logs output on stdout (beware this
	 *            is shared between all instances of JNative)
	 * 
	 * @exception NativeException
	 *                if the dll was not found, function name is incorrect...
	 * @see org.xvolks.jnative.JNative#getDLLFileExports(String)
	 */
	public JNative(String dllName, String functionName, boolean debug) throws NativeException {
		this(dllName, functionName, debug, Convention.DEFAULT);
	}

	/**
	 * Constructor
	 * 
	 * @param dllName
	 *            a String the name of the library; that DLL must be in the
	 *            library.path
	 * @param functionName
	 *            a String the name of the function this is the decorated name
	 *            (@see org.xvolks.jnative.JNative#getDLLFileExports(String))
	 * @param nativeDebug
	 *            a boolean if true the dll logs output on stdout (beware this
	 *            is shared between all instances of JNative)
	 * @param convention 
	 * 			  convention of function call          
	 *  
	 * 
	 * @exception NativeException
	 *                if the dll was not found, function name is incorrect...
	 * @see org.xvolks.jnative.JNative#getDLLFileExports(String)
	 */
	public JNative(String dllName, String functionName, boolean nativeDebug, Convention convention)
			throws NativeException {
		if (!initDone) {
			throw new IllegalStateException(
					"JNative library not loaded, sorry !");
		}
		this.convention = convention.getValue();
		mDllName = dllName;
		
		synchronized (mLibs) {
			LibDesc libDesc = getLibDesc(mDllName);
			mFunctionName = functionName;
			libDesc.numHolders ++;
			if(libDesc.handle == 0) {
				mJNativePointer = nLoadLibrary(dllName, functionName, nativeDebug);
				libDesc.handle = mJNativeHModule;
				// if (DEBUG) 
                    getLogger().log(SEVERITY.DEBUG, "Creating "+ libDesc);
			} else {
				// if (DEBUG) 
                    getLogger().log(SEVERITY.DEBUG, "Resusing "+ libDesc);
				mJNativeHModule = libDesc.handle;
				mJNativePointer = nFindFunction(mJNativeHModule, functionName, nativeDebug);
			}			
		}
		try {
			setRetVal(Type.VOID);
		} catch (IllegalAccessException e) {
			getLogger().log(SEVERITY.ERROR, e);
		}
	}

	/**
	 * Gets the native pointer of a function, can be used to pass function pointer to an other function.
	 * @return the native function pointer
	 * @throws IllegalAccessException if this JNative object have been dispised
	 */
	public int getFunctionPointer() throws IllegalAccessException {
		throwClosed();
		return mJNativePointer;
	}
	
	public void setParameter(int pos, int value) throws /* NativeException, */
	IllegalAccessException {
		setParameter(pos, Type.INT, value + "");
	}

	/**
	 * Method setParameter <br>
	 * Sets the parameter at index <code>pos</code>
	 * 
	 * @param pos
	 *            the offset of the parameter
	 * @param type
	 *            one of the enum entry (INT, STRING...)
	 * @param value
	 *            the parameter in its String representation
	 * 
	 * @throws IllegalAccessException
	 *             if this object has been disposed
	 * 
	 */
	public void setParameter(int pos, Type type, String value)
			throws IllegalAccessException {
        if(value == null)
            setParameter(pos,0);
        else
            setParameter(pos, type, (value + '\0').getBytes());
	}

	/**
	 * Method setParameter <br>
	 * Sets the parameter at index <code>pos</code>
	 * 
	 * @param pos
	 *            the offset of the parameter
	 * @param value
	 *            the String parameter (this parameter must be a in one) !
	 * @throws IllegalAccessException
	 *             if this object has been disposed
	 * 
	 */
	public void setParameter(int pos, String lValue)
			throws IllegalAccessException {
		setParameter(pos, Type.STRING, lValue);
	}

	/**
	 * Method setParameter <br>
	 * Sets the parameter at index <code>pos</code>
	 * 
	 * @param pos
	 *            the offset of the parameter
	 * @param type
	 *            one of the enum entry (INT, STRING...)
	 * @param value
	 *            the parameter in its byte[] representation
	 * 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -