|
intarsys nativeC library | |||||||||
PREV NEXT | FRAMES NO FRAMES |
See:
Description
Packages | |
---|---|
de.intarsys.nativec.api | This is the main package of the native c component. |
de.intarsys.nativec.type | Here you find the data types and data structures for native c. |
This is a generic native code wrapper.
The real memory / JNI access semantics is delegated to some concrete service implementation. Actually we dont'tprovide one of our own, the default implementation we use is JNA.
The real strength of this library is its high level model of JNI access, allowing more easy and understandable API's. We feel that at this point most of the candidates we reviewed are quite poor or hard to understand.
The design goals were as follows:
The high level model provides the following abstractions:
int a; NativeInt b = new NativeInt(); ... int result = function.invoke(Integer.class, a, b); ...the function is called using the value of "a" and a pointer to "b".
This library currently does not provide any convenience for some aspects of native calls, for example
The C part may look like this:
int intValue; float floatValue; ... int result = function(intValue, floatValue); ...
An equivalent call from Java would look like:
int intValue; float floatValue; ... int result = function.invoke(Integer.class, intValue, floatValue); ... ...This seems straightforward....
The C part may look like this:
char* string = "test"; ... int result = function(string); ...
An equivalent call from Java would look like:
String string = "test"; ... int result = function.invoke(Integer.class, string); ...String semantics are handled internally. Even the platform wide character features can be accessed quite easy - simply wrap the String in a "WideString" to indicate the special treatment on invocation marshalling.
String string = "test"; WideString wideString = new WideString(string); ... int result = function.invoke(Integer.class, wideString); ...In much the same way you can request a wide string conversion on the result.
... WideString result = function.invoke(WideString.class); String string = result.toString(); ...
The C part may look like this:
int value; ... int result = function(&value); if (value == 42) { ... } ...
An equivalent call from Java would look like:
NativeInt value = new NativeInt(); int result = function.invoke(Integer.class, value); if (value.intValue() == 42) { ... } ...The NativeObject is allocated in C memory and forwarded "by reference". This call pattern stays the same regardless of the complexity of the NativeObject - so this is the call for your Java side definition of the C struct:
// allocates memory for the struct in C MyStruct value = new MyStruct(); // call function with a pointer to the new struct int result = function.invoke(Integer.class, value); ...
my_struct *value; ... function(&value); int a = value->a; ...This is one of the rare occasions you will deal with the "NativeReference" directly. If we follow exactly the pattern we have used so far we get:
// allocate memory for holding a pointer to a struct NativeReference ptrValue = new NativeReference(MyStruct.META); // call the function with the pointer to the pointer int result = function.invoke(Integer.class, ptrValue); // dereference the result... MyStruct value = (MyStruct)ptrValue.getValue();Here's a common pattern to manage "transparent" handles that do not designate data structures you should deal with - for sure you can declare a NativeVoid subclass of you own for better readability or to add methods.
// allocate memory for holding a void pointer NativeReference ptrValue = new NativeReference(NativeVoid.META); // call the function with the pointer to the pointer int result = function.invoke(Integer.class, value); // dereference the result... NativeVoid value = (NativeVoid)ptrValue.getValue();
NativeVoid result = function.invoke(NativeVoid.class, ...);You have just wrapped a "void *" (void pointer)! Notice how you "hide" the C reference or pointer semantics. The less you think about it, the more it is intuitive :-). Using this code will return "null" in case of a "0" address.
NativeVoid is a "stateless" object, declaring to be of size "0". This is often the case with transparent handles to some proprietary / private information. Only the handle itself is used to manipulate state via the associated library functions.
In much the same way you can create a NativeStruct instances, holding public state information and allowing easy access to it.
Assume you have defined a NativeStruct subclass "MyStruct" of any memory layout. The above code sequence changes to
MyStruct structObj = function.invoke(MyStruct.class, ...);Behind this code is a simple two step process. You can do it manually if the default is not exactly what you want, for example in some cases where an address of "-1" means failure.
int address = function.invoke(Integer.class, ...); if (address == 0) { return null; } INativeHandle handle = NativeInterface.get().createHandle(address); return NativeVoid.META.createNative(handle);
The pointer, represented by the INativeHandle is wrapped by a NativeObject which is what is referenced by the pointer.
/* * Copyright (c) 2008, intarsys consulting GmbH * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * - Neither the name of intarsys nor the names of its contributors may be used * to endorse or promote products derived from this software without specific * prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */
For service and support contact
|
intarsys nativeC library | |||||||||
PREV NEXT | FRAMES NO FRAMES |