Hi!
I would like to load a DLL and unload a loaded DLL (probably not loaded by our code) using JNIWrapper.
I found the functions in kernel32.dll and tried to invoke those in order to load and unload.
I don't really want to use the DLL later, I just want to load it when I want and get rid of it when I want.
But it isn't working.
Code looks like this:
private static void loadCitrixHookDll( ) {
Pointer.Void retVal = new Pointer.Void( );
try {
Function.call( "Kernel32.dll", "LoadLibraryA", retVal, new Str( "twnhook.dll" ) );
} catch( NoSuchFunctionException exception ) {
exception.printStackTrace( );
}
System.out.println( "RetVal: " + retVal );
}
private static void unloadCitrixHookDll( ) {
Pointer.Void retVal = new Pointer.Void( );
try {
Function.call( "Kernel32.dll", "GetModuleHandleA", retVal,
new Str( "twnhook.dll" ) );
} catch( NoSuchFunctionException exception ) {
exception.printStackTrace( );
}
System.out.println( "RetVal: " + retVal );
Int value = new Int( );
try {
Function.call( "Kernel32.dll", "FreeLibrary", value, retVal );
} catch( NoSuchFunctionException exception ) {
exception.printStackTrace( );
}
}
I tried various variations (like using Library and Function). In the end, the only way I could load the library in the end is System.load() or the DefaultLibraryLoader.
But how to unload again and how to find the handle?
Probably a stupid question, but hey, I am a Java programmer. If it cannot be done using JNIWrapper then we will have to resort to using a native DLL and JNI.
But I would prefer to handle that using JNIWrapper.
So, please, what am I doing wrong, or is it impossible?
Sascha Herrmann
Hi, me again.
Sorry to have bothered you. The solution is to use the functions ending in "W" .... for whatever reason.
Just played around with it and - by pure chance - found it out.
Anyhow, loading and unloading works fine now.
Thanks anyway.
Sascha
Hi Sascha,
Thanks for letting us know that you have found the solution. I think that your code did not work because you have used Ansi version of the GetModuleHandleA function and the Str parameter, which represents a string data that depends on Unicode support of an operating system under which the code is being executed: http://www.teamdev.com/downloads/jniwrapper/javadoc/jniwrapper_v3/com/jniwrapper/Str.html
There are three possible ways to overcome such problem when you use such encoding specific API functions:
1) Use explicitly Ansi strings when you use Ansi functions:
Function.call( "Kernel32.dll", "GetModuleHandleA", retVal, new AnsiString("twnhook.dll" ) );
2) Use WideString type if you use the Unicode functions:
Function.call( "Kernel32.dll", "GetModuleHandleW", retVal, new WideString("twnhook.dll" ) );
3) And general approach:
FunctionName getModuleHandle = new FunctionName("GetModuleHandle");
Function.call( "Kernel32.dll", getModuleHandle.toString(), retVal, new Str("twnhook.dll" ) );
-Serge
Hi Serge,
ANSI ... so that's what the "A" stands for. :o)
Thanks. I had no idea. I believe I actually tried "GetModuleHandle" and received a NoSuchFunctionException (or something like that).
But that probably had a different cause. I then used depends to find the function names which only displays "GetModuleHandleA" and "GetModuleHandleW".
Of course, I picked the wrong one. Lucky me.
Thanks for your reply. I will learn in time.
Sascha