Hi,
I'm using Java 1.6 and JniWrapper 3.7 on Windows XP SP3 and I have a problem which I hope you'll be able to help me with.
I have some java code like the following;
long code1 = function1.invoke(returnVal, params);
assert 0 == code1;
long code2 = function2.invoke(returnVal, otherParams);
assert 0 == code2;
The invocation of the function1 is fine and code1 is set to 0. So I know that I have set up JniWrapper and my DLLs correctly.
However, when invoking function2 "code" is set to 3, which has the message "The system cannot find the path specified". Is there any way to find out what path the system could not find? Is that message/code generated by JniWrapper because it can't find a path or has that message come from my DLLs because they are missing some resources? Is there any way to work out what's going on?
I have no control over the DLLs so I can't examine what is going on in there. The only thing I can do is modify is the Java or system environments to generate some more logs.
As a side issue, if I remove JniWrapper 3.7 from my classpath and replace it with 3.8.1, attempting to invoke the /first/ function gives the following exception;
Exception in thread "main" com.jniwrapper.LibraryNotFoundException: þÿC cause: The specified module could not be found.
at com.jniwrapper.Library.loadLibrary(Native Method)
at com.jniwrapper.Library.a(SourceFile:169)
at com.jniwrapper.Library.load(SourceFile:134)
at com.jniwrapper.Library.getFunction(SourceFile:286)
at com.jniwrapper.Library.getFunction(SourceFile:304)
Which is strange given that all the library paths, file placements etc are all the same. It's only the version of Jni Wrapper on the class path which is different. Any ideas on that one also?
Any help you can offer will be gratefully accepted.
Many thanks,
Tom
Hi Tom,
Exception (LibraryNotFoundException: þÿC cause: The specified module could not be found) indicates that your application still uses an older version of native JNIWrapper library (jniwrap.dll) with a newer version of JNIWrapper API (jniwrap-3.8.2.jar). To solve this issue please use the new one from JNIWrapper distribution archive.
Now about the issue with a function return value. In fact the value returned by the Function.invoke() method is not a function return value itself, but a windows error code (GetLastError). Here is the information about this: http://www.teamdev.com/downloads/jniwrapper/docs/JNIWrapper-PGuide.html#AEN592 So, it seems that you need to verify the value of returnVal parameter instead after the function call.
Please try these suggestions and let me know the results.
-Serge
Hi Serge,
Thank you for the prompt response.
I replaced the jniwrap.dll with the one that matches the 3.8.2 JAR file and my LibraryNotFoundException problem went away. Thank you for the suggestion.
As for the Function.invoke() method returning a non-zero value. I understand that the long returned is a Windows error code. Indeed, I used the LastError class to get the message for the code.
The returnVal parameter is set (or remains unset) at zero. So are you saying that I can ignore the long returned by Function.invoke() and rely only on Function.invoke throwing an exception or the returnVal parameter to validate a correct native code execution? Why would the long returned by Function.invoke() return two different values for what (as far as I can tell) are perfectly fine invocations?
Thanks again for your help.
Tom
Hi Tom,
Thanks for the update.
I am saying that the Function.invoke() method is returning a value, which is an error code obtained by the GetLastError API function right after invocation of a native function in the same thread.
The following example demonstrates the usage of this return value. I took it from the com.jniwrapper.win32.ui.Wnd class of our WinPack library. This method invokes the UpdateWindow API function, analyzes the return value of a function and throws the LastErrorException exception with an appropriate error code:
/**
* Updates the client area of the window.
*/
public void update(){
Function function = User32.getInstance().getFunction("UpdateWindow");
Int result = new Int();
long errorCode = function.invoke(result, this);
if (result.getValue() == 0) {
throw new LastErrorException(errorCode, "Error updating window.");
}
}
This approach can be used for all Windows API functions and for those functions which set the last error code using the SetLastError API function. For all another supported platforms return value of Function.invoke() method can be ignored.
-Serge
Hi Serge,
Thanks again for the response.
I understand what you're saying and I understand where this error code has come from.
My situation is this. My DLL which JNI Wrapper wraps is a black box and this Windows error code is unexpected. Is there any way I can get more information about this windows error code? I would like to be able to view some kind of debug message telling me why this error code is being thrown.
I know that the message which accompanies this error code is "The specified path cannot be found." but I would like to know which path cannot be found and what component was looking for it.
Like I said, some function calls return okay, but others return this Windows error code and I need to work out why that error code has been returned.
Many thanks,
Tom
Hi Tom,
If you are using functions from Windows API then you can get only an error code, which can be translated to an error message using the FormatMessage Windows API function, or using the appropriate LastError.getMessage() wrapper function. But in this case you will only get "The specified path cannot be found" message, without specifying the additional details. That's only way to obtain an error information in Windows API.
This is possible only if a function itself provides such detailed diagnostic information in some way. But usually such information is not available at runtime.
-Serge
Hi Serge,
Thanks for the response. I feared that would be the case, I was hoping that there might be a way to put JNIWrapper into a debug mode which showed exactly what it was doing/loading/executing.
Nevermind, though, I'll have to figure something else out.
Thanks again,
Tom