Technical
Get answers to most commonly asked technical questions about JNIWrapper. If you can’t find the answer here, please send us your question using the support forum, and we will add it to this FAQ after answering you.
I developed my program on Windows XP (NT/2000) and it doesn’t run on Windows Me (95/98).
While JNIWrapper supports all versions of Windows operating systems, it is possible to invoke some OS-specific function or use a library that is not available on certain versions of Windows. For example, the SignalObjectAndWait function is not supported on Windows 95/98/Me. Therefore, if your program uses such a function, it will not run on the Windows versions that do not support it.
Can I write my own types for JNIWrapper?
Yes. The only thing you should do is extend the com.jniwrapper.Parameter class.
I heard that NIO introduced in version 1.4 provides better performance for accessing the native memory. Does JNIWrapper make use of NIO?
Yes, if the NIO package is available, JNIWrapper will use it.
I think that some safety checks are slowing down my program - can I disable them?
In version 1.4, NIO buffers perform range checks for all operations. We have found an underlying implementation class that can be used to access native memory without those checks. If your program accesses native data a lot, you can try to run it by defining the com.jniwrapper.useunsafe system property. This may give your program some extra performance. This option will not affect the programs running on J2SE version 1.3.
How can I further improve fail-safety of my program that uses JNIWrapper?
All function calls are already protected from access violations inside the native code, and those access violations are converted to Java exceptions. Under JDK 1.3.x, all memory accesses are protected in the same way, but this is not the case where NIO is used. Though NIO access is faster, it can lead to crashes with some ill-behaved libraries that return pointers to invalid memory locations. If your program interacts with such a library, you may want to switch the memory access behavior back to 1.3.x scheme by defining the com.jniwrapper.safemem system property. This option will have no effect on the programs running under JDK version 1.3.x.
Why does JNIWrapper for Linux require JRE 1.4.x?
To prevent failures caused by memory access violations on the native code side, JNIWrapper for Linux employs the signal-chaining feature that is available in JDK since version 1.4.
We consider developing a version that would run on JRE version 1.3.x if there is a demand for that. If you need such version, please send your requests to sales@teamdev.com
What should I not expect from JNIWrapper?
JNIWrapper provides means for calling native functions from libraries, but there are some things we cannot do at the moment. Here are the most remarkable cases:
JNIWrapper does not provide integration with C++ yet. This is planned for future versions. However, if you need to call a C function that takes a pointer to C++ object as a parameter, then it is possible to do that using JNIWrapper. You can operate with a C++ object using the Pointer.Void class. For example:
// C++ class
class A {
public:
A() {}
}
// C function
void test(A* a);
// JNIWrapper function call
Function test = ...; // Pointer to C++ object
// the object can be created on the native side
// and then returned to Java via Pointer.Void
Pointer.Void objectPtr = ...;
test.invoke(null,& objectPtr);
There is no support for C++ exception handling.
These and many other features are planned for future versions. The order of their implementation will depend on the feedback we receive. If you need a certain feature, please contact us at sales@teamdev.com.
How do I use multi-dimensional arrays with JNIWrapper?
To use correct parameters and initialize them properly, you should understand the actual data structure that represents the array in question. There are two different cases of array storage in the C language: the linear storage and array of pointers to array (of pointers to array, etc.) of actual elements.
In the first case, all data is stored sequentially, so, for example, the element at [1][1] of a 3 by 3 array is stored at offset 1 * 3 + 1 = 4 from the base pointer. For such arrays, you should allocate a linear array big enough to hold all the elements and access the elements using an index calculation function that converts the multi-dimensional index to the linear index.
In the second case, the actual data is stored only in the "leaf" arrays and you have to allocate arrays of pointers to arrays of actual data. Make sure that you have all intermediate arrays allocated and pointing to the appropriate children. To access data in this case, you will have to get through all the intermediate arrays to the bottom level and access the required value from the bottommost array.
It is often quite easy to determine the storage type from the declaration: when all array dimensions (except probably the first one) are specified, the array is stored sequentially; otherwise, it is stored as "arrays of arrays".
For example:
float a[3][4][5], int b[][100] - sequential storage,
char argv[][], double points[][] - "arrays of arrays"
I am calling a function with correct parameters, but keep getting an exception about incorrect parameter types.
Please verify that you are using the correct calling convention. The defaults are: stdcall for Windows as it is used by most of the Windows API, and cdecl for Linux - it is used by almost all libraries.
Where can I find a reference containing a one-to-one mapping of your Parameter classes with their relevant C data types?
Please check the JNIWrapper documentation (Programmer’s Guide). The quick reference with additional comments is also available online.
I get the following error: ciceroUIWNDFRAME: javaw.exe - apllication error
This error is not caused by JNIWrapper, but rather by Microsoft Office's Speech and Handwriting Recognition. In order to continue using JNIWrapper, you will need to disable this Microsoft feature. To disable the Speech and Handwriting Recognition:
Click "Start" button at the bottom left of Microsoft Windows.
Click "Control Panel."
Click "Add/Remove Programs."
Click "Microsoft Office."
Click on the "Change" button
Browse to "Office Shared Features."
Click on "Alternative User Input."
For both the Speech and Handwriting Recognition, select "Not available."
Once this is disabled, the CiceroUIWndFrame messages disappear. Also, please check this Microsoft support site for a more detailed set of steps to remove these tools: http://support.microsoft.com/default.aspx?scid=kb;%5BLN%5D;326526.
JNIWrapper fails to start and throws UnsatisfiedLinkError: "java.lang.UnsatisfiedLinkError: Cannot find JNIWrapper native library in java.library.path." even though jniwrap64.dll is installed correctly.
64-bit version of JNIWrapper library (jniwrap64.dll) requires MSVCR80.dll runtime library to be installed in the system.
JNIWrapper native library fails to load on my Linux station. How can I find out why?
You need to check the presence of required system libraries and their versions. To do it, run the ld utility with a full path to the JNIWrapper native library as its parameter.
Which Java version do you recommend to use with JNIWrapper and your other products?
You can use any Java version starting from 1.4.
If you use Java 1.5, we recommend updating to version 1.5.0_06.
I would like to invoke code from a DLL that I generated with C#. Can I do it with JNI Wrapper, and if possible how?
Answer: JNIWrapper is not designed for integration with .NET libraries which are created on C# or any other .NET programming language. In fact such libraries have architecture which completely differs from conventional Win32 DLL libraries.
Nevertheless it is possible to integrate with a .NET library, but only if this library provides COM Interop level. In this case you can use our ComfyJ product.
How I can distribute my native library or jniwrap.dll/dylib/jnilib files with my application?
Answer: The simplest way to deploy native libraries (and it’s applicable for all supported platforms) is to put these native libraries to any JAR file, which is included into class path of your application. This could be JNIWrapper JAR file as well. In this case JNIWrapper itself will take care of finding and loading the corresponding native library at runtime. The main requirement is that all native libraries should reside in a root folder of a JAR file.