📄 funcptr.java
字号:
/*
* FuncPtr.java -
*
* This file is part of the Jawin Project: http://jawinproject.sourceforge.net/
*
* Please consult the LICENSE file in the project root directory,
* or at the project site before using this software.
*/
/* $Id: FuncPtr.java,v 1.3 2004/06/14 20:00:29 arosii_moa Exp $ */
package org.jawin;
import org.jawin.io.NakedByteStream;
import org.jawin.marshal.*;
/**
* Class for working with a reference to a single Win32 function exposed in standard DLL's.
* The <a href="../../../jawinuserguide_dll.html">Jawin Userguide - Calling
* a DLL Entry Point</a> document should be consulted about how to use this class.
* <br><br>
* Contains several <code>invoke_*</code>-methods for some standard function signatures.
* These falls in three groups:
* <ul>
* <li><code>invoke_I</code>-methods for native methods with a standard int as [retval]</li>
* <li><code>invoke_OI</code>-methods for native methods with a last parameter being
* a [out] int</li>
* <li><code>invoke_S</code>-methods for native methods returning a byte array (can be
* used for methods returning structs)</li>
* </ul>
* Please notice that because of the TYPEDEF in C/C++ many method signatures are
* covered by the relatively few <code>invoke_*</code>-methods, as eg. HWND, HRESULT,
* LONG etc. all can be represented as Java int's.
* <br><br>
* If working with a function that does not match one of the standard signatures, use the
* generic {@link #invoke(String, int, NakedByteStream, Object[], ReturnFlags)}.
*
* @see <a href="../../../jawinuserguide_dll.html">The Jawin Userguide
* - Calling a DLL Entry Point</a>
* @version $Revision: 1.3 $
* @author Stuart Halloway, http://www.relevancellc.com/halloway/weblog/<br>
* Morten Andersen, arosii_moa (at) users.sourceforge.net
*/
public final class FuncPtr {
/** The function pointer. */
private int peer;
/** The dll handle. */
private int dllHandle;
/** The library name. */
private final String dll;
/** The entry point name. This may not be the same as the name in source code,
use DUMPBIN /EXPORTS to get the exact name. */
private final String name;
private final int hash;
/**
*
* @param dll the name of a DLL (can be either just the name of the
* DLL or a full path - use backslashes (\)). Note, that the name
* is not case sensitive and that the ".dll"-part is optional.
* The exact syntax for the parameter can be found in the MSDN documentation for
* {@link <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/loadlibrary.asp">LoadLibrary</a>}.
* @param name the function name exposed in the DLL.
* @throws COMException if unable to load the DLL or find the function.
* @throws NullPointerException if either dll or name is null.
*/
public FuncPtr(String dll, String name) throws COMException {
if ((dll == null) || (name == null)) {
throw new NullPointerException("neither the DLL name (" + dll +
") or the function name (" + name + ") can be null");
}
this.name = name;
this.dll = dll;
dllHandle = Bootstrap.loadLibrary(dll);
peer = Bootstrap.loadFunction(dllHandle, name);
hash = dll.hashCode() ^ name.hashCode();
}
public int hashCode() {
return hash;
}
/**
* @return the function pointer
* @throws IllegalStateException if this FuncPtr has been closed.
*/
public int getPeer() {
checkState();
return peer;
}
public boolean equals(Object o) {
if (o == null)
return false;
if (o.getClass() != getClass())
return false;
if (o == this)
return true;
FuncPtr fp = (FuncPtr) o;
return (dll.equals(fp.dll) && name.equals(fp.name));
}
public String toString() {
return "[" + dll + ":" + name + "]";
}
/**
* Call to "free" the function pointer. Windows automatically
* manages a reference count for each library and will close the
* library if this was the last active function.
* <br><br>
* After close() has been called the FuncPtr should not be
* used anymore as all invoke's will throw an
* IllegalStateException.
*/
public synchronized void close() throws COMException {
if (peer != 0) {
Bootstrap.freeLibrary(dllHandle);
dllHandle = 0;
peer = 0;
}
}
/**
* backup for releasing resources, by calling {@link #close()}.
*/
protected void finalize() throws Throwable {
close();
super.finalize();
}
/**
* @throws IllegalStateException if this FuncPtr has been closed.
*/
private void checkState() {
if (peer == 0) {
throw new IllegalStateException(toString() + " has been closed");
}
}
/**
* generic method for calling native methods that do not match any of the
* invoke_* methods. If the caller is using a {@link NakedByteStream}
* for building the stack-bytes, the
* {@link #invoke(String, int, NakedByteStream, Object[], ReturnFlags)}
* shortcut method is prefered.
*
* @param instructions the marshalling instructions for marshalling both
* the stack-array onto the native stack (this is the [in]-parameters)
* and marshalling the [return] and [out]-parameters onto the
* returned byte array. Is on the form <code>xx:y:zz</code>,
* where <code>xx</code> is for the [in]-marshalling, <code>y</code>
* is for the [return]-marshalling, and <code>zz</code> is for any
* [out]-marshalling if present. See the Jawin documentation for
* more about the instruction-strings.
* @param stackSize the size of the call stack on the native side that
* the content of the argStream-array should be marshalled to.
* @param argStreamSize the number of relevant bytes in the argStream-array (often
* a {@link org.jawin.io.NakedByteStream} is used for the argStream-array,
* in which case the array will not be full.
* @param argStream the bytes that should be marshalled to the stack on the native
* side. The length of this array can NOT be smaller than argStreamSize.
* @param objectArgs [in/out] used if any java-object should be passed
* back and forth into the native code.
* @param flags used for specifying the native error handling, can not be null.
*
* @return the [return] and [out] parameters from the native call, serialized
* following the marshalling-instructions given the second and third
* part of the instructions string.
*
* @throws COMException if the native method failed.
* @throws NullPointerException if flags is null.
* @throws ArrayIndexOutOfBoundsException if argStreamSize is bigger than the
* length of the argStream-array.
* @throws IllegalStateException if this FuncPtr has been closed.
*/
public byte[] invoke(String instructions, int stackSize, int argStreamSize,
byte[] argStream, Object[] objectArgs, ReturnFlags flags) throws COMException {
checkState();
return GenericStub.win32Invoke(peer, instructions, stackSize, argStreamSize,
argStream, objectArgs, flags);
}
/**
* shortcut method for calling {@link #invoke(String, int, int, byte[], Object[], ReturnFlags)}
* when using a {@link NakedByteStream} for building the argStream-bytes.
*
* @param argStream the NakedByteStream containing the argStream-bytes. Null is
* equal to an empty argStream.
*
* @see #invoke(String, int, int, byte[], Object[], ReturnFlags)
*/
public byte[] invoke(String instructions, int stackSize, NakedByteStream argStream,
Object[] objectArgs, ReturnFlags flags) throws COMException {
int argStreamSize = (argStream != null ? argStream.size() : 0);
byte[] argStreamArray = (argStream != null ? argStream.getInternalBuffer() : null);
return invoke(instructions, stackSize, argStreamSize, argStreamArray,
objectArgs, flags);
}
/**
* for calling native methods taking no args, and returning an int.
*
* @param flags used for specifying the native error handling, can not be null.
* @return the result of the native method.
* @throws COMException if the native method failed.
* @throws NullPointerException if flags is null.
* @throws IllegalStateException if this FuncPtr has been closed.
*/
public int invoke_I(ReturnFlags flags) throws COMException {
checkState();
return SharedStubs.invoke_I(peer, flags.value);
}
/**
* for calling native methods taking one int arg, and returning an int.
*
* @param arg0 the arg that should be passed to the native method.
* @param flags used for specifying the native error handling, can not be null.
* @return the result of the native method.
* @throws COMException if the native method failed.
* @throws NullPointerException if flags is null.
* @throws IllegalStateException if this FuncPtr has been closed.
*/
public int invoke_I(int arg0, ReturnFlags flags) throws COMException {
checkState();
return SharedStubs.invokeI_I(arg0, peer, flags.value);
}
/**
* for calling native methods taking two int args, and returning an int.
*
* @see #invoke_I(int, ReturnFlags)
*/
public int invoke_I(int arg0, int arg1, ReturnFlags flags) throws COMException {
checkState();
return SharedStubs.invokeII_I(arg0, arg1, peer, flags.value);
}
/**
* for calling native methods taking four int args, and returning an int.
*
* @see #invoke_I(int, ReturnFlags)
*/
public int invoke_I(int arg0, int arg1, int arg2, int arg3, ReturnFlags flags) throws COMException {
checkState();
return SharedStubs.invokeIIII_I(arg0, arg1, arg2, arg3, peer, flags.value);
}
/**
* for calling native methods taking one String arg, and returning an int.
*
* @param arg0 the arg that should be passed to the native method as a BSTR.
* @param flags used for specifying the native error handling, can not be null.
* @return the result of the native method.
* @throws COMException if the native method failed.
* @throws NullPointerException if flags is null.
* @throws IllegalStateException if this FuncPtr has been closed.
*/
public int invoke_I(String arg0, ReturnFlags flags) throws COMException {
checkState();
return SharedStubs.invokeG_I(arg0, peer, flags.value);
}
/**
* for calling native methods taking two String args, and returning an int.
*
* @see #invoke_I(String, ReturnFlags)
*/
public int invoke_I(String arg0, String arg1, ReturnFlags flags) throws COMException {
checkState();
return SharedStubs.invokeGG_I(arg0, arg1, peer, flags.value);
}
/**
* for calling native methods taking one int and one String args, and returning an int.
*
* @see #invoke_I(int, ReturnFlags)
* @see #invoke_I(String, ReturnFlags)
*/
public int invoke_I(int arg0, String arg1, ReturnFlags flags) throws COMException {
checkState();
return SharedStubs.invokeIG_I(arg0, arg1, peer, flags.value);
}
/**
* for calling native methods taking one int, two String and one int args,
* and returning an int (used for MessageBoxW).
*
* @see #invoke_I(int, ReturnFlags)
* @see #invoke_I(String, ReturnFlags)
*/
public int invoke_I(int arg0, String arg1, String arg2, int arg3, ReturnFlags flags) throws COMException {
checkState();
return SharedStubs.invokeIGGI_I(arg0, arg1, arg2, arg3, peer, flags.value);
}
/**
* for calling native methods taking one pointer to a byte array, and returning an int.
* Can for example be used for methods taking a pointer to a struct, like
* DispatchMessageW.
*
* @param arg0 the arg that should be passed to the native method as a pointer to a byte array.
* @param flags used for specifying the native error handling, can not be null.
* @return the result of the native method.
* @throws COMException if the native method failed.
* @throws NullPointerException if flags is null.
* @throws IllegalStateException if this FuncPtr has been closed.
*/
public int invoke_I(byte[] arg0, ReturnFlags flags) throws COMException {
checkState();
return SharedStubs.invokeP_I(arg0, peer, flags.value);
}
/**
* for calling native methods taking two int args, where the last int is a [out] parameter.
* This [out] parameter will be returned by this function. An example of such a
* function is GetNumberOfEventLogRecords().
*
* @param arg0 the [in] int argument.
* @param flags used for specifying the native error handling, can not be null.
* @return the result of the native method.
* @throws COMException if the native method failed.
* @throws NullPointerException if flags is null.
* @throws IllegalStateException if this FuncPtr has been closed.
*/
public int invoke_OI(int arg0, ReturnFlags flags) throws COMException {
checkState();
return SharedStubs.invokeIO(arg0, peer, flags.value);
}
/**
* for calling native methods taking five int args, where the first four are standard
* [in] parameters and the last int is a [out] parameter.
*
* @see #invoke_OI(int, ReturnFlags)
*/
public int invoke_OI(int arg0, int arg1, int arg2, int arg3, ReturnFlags flags) throws COMException {
checkState();
return SharedStubs.invokeIIIIO(arg0, arg1, arg2, arg3, peer, flags.value);
}
/**
* for calling native methods taking one [in] int, one [in] String and one [out] int arg.
*
* @see #invoke_OI(int, ReturnFlags)
*/
public int invoke_OI(int arg0, String arg1, ReturnFlags flags) throws COMException {
checkState();
return SharedStubs.invokeIGO(arg0, arg1, peer, flags.value);
}
/**
* for calling native methods taking one int arg, and returning a byte array of
* a specified size (typically used when calling methods returning a struct
* with a known byte-size).
*
* @param arg0 the [in] int argument.
* @param returnSize the size of the byte array to return.
* @param flags used for specifying the native error handling, can not be null.
* @return the result of the native method - will be a byte array with size returnSize.
* @throws COMException if the native method failed.
* @throws NullPointerException if flags is null.
* @throws IllegalStateException if this FuncPtr has been closed.
*/
public byte[] invoke_S(int arg0, int returnSize, ReturnFlags flags) throws COMException {
checkState();
return SharedStubs.invokeI_S(arg0, returnSize, peer, flags.value);
}
/**
* for calling native methods taking one pointer to a byte array, and returning
* a byte array of a specified size.
*
* @see #invoke_S(int, int, ReturnFlags)
*/
public byte[] invoke_S(byte[] arg0, int returnSize, ReturnFlags flags) throws COMException {
checkState();
return SharedStubs.invokeP_S(arg0, returnSize, peer, flags.value);
}
/**
* for calling native methods taking one pointer to a byte array and one int args,
* and returning a byte array of a specified size.
*
* @see #invoke_S(int, int, ReturnFlags)
*/
public byte[] invoke_S(byte[] arg0, int arg1, int returnSize, ReturnFlags flags) throws COMException {
checkState();
return SharedStubs.invokePI_S(arg0, arg1, returnSize, peer, flags.value);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -