1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!--NewPage-->
<HTML>
<HEAD>
<!-- Generated by javadoc (build 1.5.0_08) on Mon Nov 02 09:55:40 CET 2009 -->
<TITLE>
Overview (intarsys nativeC library)
</TITLE>
<META NAME="keywords" CONTENT="Overview, intarsys nativeC library">
<LINK REL ="stylesheet" TYPE="text/css" HREF="javadocstyle.css" TITLE="Style">
<SCRIPT type="text/javascript">
function windowTitle()
{
parent.document.title="Overview (intarsys nativeC library)";
}
</SCRIPT>
<NOSCRIPT>
</NOSCRIPT>
</HEAD>
<BODY BGCOLOR="white" onload="windowTitle();">
<!-- ========= START OF TOP NAVBAR ======= -->
<A NAME="navbar_top"><!-- --></A>
<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
<TR>
<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
<A NAME="navbar_top_firstrow"><!-- --></A>
<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
<TR ALIGN="center" VALIGN="top">
<TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Overview</B></FONT> </TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT> </TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT> </TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT> </TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
</TR>
</TABLE>
</TD>
<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
<i>
<b>intarsys nativeC library</b>
</i>
</EM>
</TD>
</TR>
<TR>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
PREV
NEXT</FONT></TD>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
<A HREF="index.html?overview-summary.html" target="_top"><B>FRAMES</B></A>
<A HREF="overview-summary.html" target="_top"><B>NO FRAMES</B></A>
<SCRIPT type="text/javascript">
<!--
if(window==top) {
document.writeln('<A HREF="allclasses-noframe.html"><B>All Classes</B></A>');
}
//-->
</SCRIPT>
<NOSCRIPT>
<A HREF="allclasses-noframe.html"><B>All Classes</B></A>
</NOSCRIPT>
</FONT></TD>
</TR>
</TABLE>
<A NAME="skip-navbar_top"></A>
<!-- ========= END OF TOP NAVBAR ========= -->
<HR>
<CENTER>
<H1>
intarsys nativeC library
</H1>
</CENTER>
This is a generic native code wrapper.
<P>
<B>See:</B>
<BR>
<A HREF="#overview_description"><B>Description</B></A>
<P>
<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
<B>Packages</B></FONT></TH>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD WIDTH="20%"><B><A HREF="de/intarsys/nativec/api/package-summary.html">de.intarsys.nativec.api</A></B></TD>
<TD>This is the main package of the native c component.</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD WIDTH="20%"><B><A HREF="de/intarsys/nativec/type/package-summary.html">de.intarsys.nativec.type</A></B></TD>
<TD>Here you find the data types and data structures for native c.</TD>
</TR>
</TABLE>
<P>
<A NAME="overview_description"><!-- --></A>
<P>
This is a generic native code wrapper.
<h2><a name="Content">Content</a></h2>
<ol type="a" >
<li><a href="#Overview">Overview</a></li>
<li><a href="#Manual">Manual</a></li>
<li><a href="#License">License</a></li>
<li><a href="#Support">Service and support</a></li>
</ol>
<!-- ============== -->
<hr></hr>
<h2><a name="Overview">Overview</a></h2>
This is "another" JNI wrapping library, but in some regards quite different.
<p>
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.
<p>
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.
<p>
The design goals were as follows:
<ul>
<li>Provide access to all levels of a native interface. As we can not forsee what different libaries and
systems will work together, access is provided from bottom up using the plain address as the least common
denominator. </li>
<li>Provide clean abstractions</li>
<li>Differentiate between a "pointer" or "memory handle" and the data semantics. This allows to work
as well using plain pointer arithmetics as object state access. </li>
</ul>
<p>
The high level model provides the following abstractions:
<ul>
<li>Interface
</li>
The concrete implementation for accessing JNI. This interface is quite small and allows for
the adaption of many JNI libraries out there. It should not be to hard to create one of your own.
<li>Library
</li>
The loadable library providing state and behavior.
<li>Function
</li>
The behavior part of the library, accepting parameters and return results.
<li>Handle
</li>
An abstraction of a pointer, without any data specific features. This could be viewed
as a plain wrapper around an address, another representation for "void *".
<li>Object
</li>
The data referenced by a handle (or pointer). The object deals with the bytes referenced by the handle.
The object defines the semantics of how to interpret the memory referenced by the handle.
The handle defines "where" to find data, the object defines "what" data you will find there -
it deals only with the "dereferenced" part of the handle.
On the C side, the object is always represented by the handle / pointer. This means that an object
is always used and forwarded by reference. Do not confuse this with the handling on primitive
types. In this code snippet
<pre>
int a;
NativeInt b = new NativeInt();
...
int result = function.invoke(Integer.class, a, b);
...
</pre>
the function is called using the value of "a" and a pointer to "b".
</li>
</ul>
<p>
This library currently does not provide any convenience for some aspects of
native calls, for example
<ul>
<li>primitive arrays</li>
<li>float / double support</li>
<li>String encodings</li>
<li>callbacks</li>
<li>maybe other features we didn't need until now and so are not aware of..</li>
</ul>
The underlying infrastructure (JNA) may handle such constructs, but as long as the
semantics is not defined on this library level, you should expect unportable
behavior.
We propose, even if not convenient, to express all call semantics using documented
features only. Feel free to ask for the inclusion of more library features.
<h2><a name="Manual">Manual</a></h2>
<h3>Common scenarios</h3>
<h4>Call functions with primitive types</h4>
The most simple calls use only primitive types. These are mapped by the "invoke" itself
using builtin rules to target the C types.
<p>
The C part may look like this:
<pre>
int intValue;
float floatValue;
...
int result = function(intValue, floatValue);
...
</pre>
<p>
An equivalent call from Java would look like:
<pre>
int intValue;
float floatValue;
...
int result = function.invoke(Integer.class, intValue, floatValue);
...
...
</pre>
This seems straightforward....
<h4>Call functions with String parameters</h4>
The first problems are expected when dealing with strings or char* on the C side. But
no problem here:
<p>
The C part may look like this:
<pre>
char* string = "test";
...
int result = function(string);
...
</pre>
<p>
An equivalent call from Java would look like:
<pre>
String string = "test";
...
int result = function.invoke(Integer.class, string);
...
</pre>
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.
<pre>
String string = "test";
WideString wideString = new WideString(string);
...
int result = function.invoke(Integer.class, wideString);
...
</pre>
In much the same way you can request a wide string conversion on the result.
<pre>
...
WideString result = function.invoke(WideString.class);
String string = result.toString();
...
</pre>
<h4>Call with parameters "by reference" (out parameters)</h4>
Other functions return values via "out" parameters, via references to C memory.
<p>
The C part may look like this:
<pre>
int value;
...
int result = function(&value);
if (value == 42) {
...
}
...
</pre>
<p>
An equivalent call from Java would look like:
<pre>
NativeInt value = new NativeInt();
int result = function.invoke(Integer.class, value);
if (value.intValue() == 42) {
...
}
...
</pre>
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:
<pre>
// 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);
...
</pre>
<h4>Wrapping pointers returned from out parameters</h4>
With C you find quite often a pointer to a newly create memory chunk returned via
an out parameter.
<pre>
my_struct *value;
...
function(&value);
int a = value->a;
...
</pre>
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:
<pre>
// 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();
</pre>
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.
<pre>
// 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();
</pre>
<h4>Wrapping a pointer returned as function result</h4>
Many functions return handles to newly created objects. Wrapping this result to the
INativeObject framework is simply a matter of declaration:
<pre>
NativeVoid result = function.invoke(NativeVoid.class, ...);
</pre>
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.
<p>
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.
<p>
In much the same way you can create a NativeStruct instances, holding public state information
and allowing easy access to it.
<p>
Assume you have defined a NativeStruct subclass "MyStruct" of any memory layout. The above
code sequence changes to
<pre>
MyStruct structObj = function.invoke(MyStruct.class, ...);
</pre>
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.
<ul>
<li>Create the INativeHandle wrapper. This object represents a memory address and implements
some access primitives</li>
<li>Use the INativeHandle to build the INativeObject wrapper that is situated at this memory location.
This can be any of the INativeObject subclasses, such as a primitive, composite or even void representation.</li>
</ul>
<pre>
int address = function.invoke(Integer.class, ...);
if (address == 0) {
return null;
}
INativeHandle handle = NativeInterface.get().createHandle(address);
return NativeVoid.META.createNative(handle);
</pre>
<p>
The pointer, represented by the INativeHandle is wrapped by a NativeObject which is
what is referenced by the pointer.
<h4>Primitive arrays and buffers</h4>
You can call a native function using primitive arrays the same way as using plain primitives.
The basic marshalling will map the values in both direction, so you see C side changes in the
Java array directly.
Conceptually you should treat such a call as follows:
The memory is managed by the library. Upon entry, memory is allocated in C address space, the data is copied.
The C function is called with the pointer to the newly allocated memory. After
termination of the function, memory is copied back to Java address space, and the
newly allocated memory is discarded. Access to the memory in C address space is no longer valid!
So, if you want to provide a buffer to C for use even outside the function call this
is not the correct way! You must use NativeObject instances, for example NativeBuffer,
to force C memory allocation resident in memory (controlled by your application).
To optimize the marshalling between Java and C you may use direct "ByteBuffer" objects. Using
this objects marshalling MAY be optimized by the underlying implementation to share memory
between Java and C.
In any case you may use a NativeBuffer and access the memory allocated in heap space from both
sides. NativeBuffer can be seen as an explicit equivalent to a DirectBuffer.
<h2><a name="License">License</a></h2>
<pre>
/*
* 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.
*/
</pre>
<h2><a name="Service & Support">Service & Support</a></h2>
If you need further support, feel free to contact us.
intarsys consulting GmbH<br>
Bahnhofplatz 8<br>
76137 Karlsruhe<br>
Fon +49 721 38479-0<br>
Fax +49 721 38479-60<br>
info@intarsys.de<br>
www.intarsys.de<br>
<p>For service and support contact</p>
<ol>
<li>EMail support: <a href="mailto://support@intarsys.de">support@intarsys.de</a></li>
</ol>
<P>
<P>
<HR>
<!-- ======= START OF BOTTOM NAVBAR ====== -->
<A NAME="navbar_bottom"><!-- --></A>
<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
<TR>
<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
<A NAME="navbar_bottom_firstrow"><!-- --></A>
<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
<TR ALIGN="center" VALIGN="top">
<TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Overview</B></FONT> </TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT> </TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT> </TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Use</FONT> </TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="index-files/index-1.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
</TR>
</TABLE>
</TD>
<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
<i>
<b>intarsys nativeC library</b>
</i>
</EM>
</TD>
</TR>
<TR>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
PREV
NEXT</FONT></TD>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
<A HREF="index.html?overview-summary.html" target="_top"><B>FRAMES</B></A>
<A HREF="overview-summary.html" target="_top"><B>NO FRAMES</B></A>
<SCRIPT type="text/javascript">
<!--
if(window==top) {
document.writeln('<A HREF="allclasses-noframe.html"><B>All Classes</B></A>');
}
//-->
</SCRIPT>
<NOSCRIPT>
<A HREF="allclasses-noframe.html"><B>All Classes</B></A>
</NOSCRIPT>
</FONT></TD>
</TR>
</TABLE>
<A NAME="skip-navbar_bottom"></A>
<!-- ======== END OF BOTTOM NAVBAR ======= -->
<HR>
<i>Copyright © 2008 <a href=http://www.intarsys.de/ target=_top>intarsys consulting GmbH</a>. All Rights Reserved.</i>
</BODY>
</HTML>
|