📄 delphi-jni-1.html
字号:
<HTML>
<HEAD>
<meta name="keywords" content="Delphi, JNI, Java Native Interface, jni.pas, jni_md.pas, Borland, Inprise, Java">
<xxxlink rel="stylesheet" type="text/css" href="jni.css">
<style>
<!--
.Note1
{
margin-left: 0;
xfont-style: Italic;
background-color: rgb(255,255,240);
border-style: outset;
border-color: teal;
border-width: thin;
font-weight: normal;
vertical-align: top;
padding-top: 5px;
padding-bottom: 5px;
padding-left: 5px;
padding-right: 5px;
}
.SectionHeader
{
margin-left: 0;
font-size : 14pt;
font-weight : bold;
background-color: rgb(255,255,204);
border-style: solid;
border-color: black;
border-width: thin;
xvertical-align: top;
padding-top: 5px;
padding-bottom : 5px;
padding-left: 20px;
padding-right: 20px;
}
-->
</style>
<TITLE>Using the Java Native Interface with Delphi (Part One - Introduction and Tutorial)</TITLE>
</HEAD>
<BODY BGCOLOR="#e0e0e0">
<a name="Top">
<H2><center>
Using the Java Native Interface with Delphi<br>
<font size=+1>(Part One - Introduction and Tutorial)</font>
</center></H2>
<center><a href="mailto:jni@matthewmead.com">Matthew Mead</a></center>
<p>
<a href="http://www.pacifier.com/~mmead/jni/delphi/index.html">Home Page (on the Web) - News and Updates</a>
<p>
Part One - Introduction and Tutorial
<br>
<a href="delphi-jni-2.html">Part Two - Techniques and Examples</a>
<br>
<a href="delphi-jni-3.html">Part Three - The Invocation API</a>
<p>
<a href="http://www.delphi-jedi.org"><img src="gifs/btn_jedinow.gif" width="116" height="31"></a>
<br>
<h3><A NAME="Contents">Contents</A></h3>
<blockquote>
<table border=0 cellspacing=8 cellpadding=0>
<tr><td align=right><A HREF="#QuickStart">Quick Start</A></td><td>If you're familiar with Delphi and JNI and want to get started right away.</td></tr>
<tr><td align=right><A HREF="#Background">Background</A></td><td>Why JNI? Why Delphi?</td></tr>
<tr><td align=right><A HREF="#Overview">Overview</A></td><td>What's here?</td></tr>
<tr><td align=right><A HREF="#Translation">Translation</A></td><td>A brief look at translating the C/C++ header file to Delphi.</td></tr>
<tr><td align=right><A HREF="#Example">Example</A></td><td>The canonical <i>HelloWorld</i> program.</td></tr>
<tr><td align=right><A HREF="#CloserLook">A Closer Look</A></td><td>The <i>HelloWorld</i> program in excruciating detail.</td></tr>
<tr><td align=right><A HREF="#Troubleshooting">Troubleshooting</A></td><td>Typical errors when programming with the JNI.</td></tr>
<tr><td align=right><A HREF="#Debugging">Debugging</A></td><td>Stepping through your Delphi DLL at runtime.</td></tr>
<tr><td align=right><A HREF="#Summary">Summary</A></td><td>What's next?</td></tr>
<tr><td align=right><A HREF="#Resources">Helpful Resources</A></td><td>Sources to help you with Delphi and the JNI</td></tr>
</table>
</blockquote>
<div class="SectionHeader">
<A NAME="QuickStart">Quick Start</a>
</div>
<BLOCKQUOTE>
C/C++ programmers should check out these pages:
<p>
<BLOCKQUOTE>
<A HREF="http://www.cs.pdx.edu/~antoy/Courses/Advanced/units/jni/index.html">
Programming with the Java Native Interface</a> This is a tutorial that shows how to use the
Java Native Interface with Linux, Solaris, and Windows NT.
<br>
<a href="http://www.pacifier.com/~mmead/jni/cs510jip/index.html">
Using the Java Native Interface with C++</a> This has a lot of examples of how you might
use the Java Native Interface. Contrasts Sun's vision with Microsoft's. Also includes some
crude benchmarks. This is an older document. (January 1998)
</BLOCKQUOTE>
</BLOCKQUOTE>
<BLOCKQUOTE>
Experienced JNI/Delphi programmers should grab <a href="src/jni_pas.html">jni.pas</a> and <a href="src/jni_md_pas.html">jni_md.pas</a>
and get started. The files are syntax-highlighted using a tool called <a href="http://ww6.borland.com/codecentral/ccweb.exe/listing?id=14531">YAPP</a>,
which is was written by John Kaster of <a href="http://www.borland.com/">Borland/Inprise</a>.) Also, all of the source files used
in this tutorial can be downloaded <a href="zips/helloworld.zip">here</a>.
<p>
<i>Delphi programmers may also want to check out the C/C++ links above. Although those pages are targeted at C/C++ programmers, there's a wealth of
information about the Java Native Interface (not necessarily related to C/C++) that may not be duplicated here.</i>
<p>
<a href="#Top">Back to top</a>
</BLOCKQUOTE>
<div class="SectionHeader">
<A NAME="Background">Background</A>
</div>
<BLOCKQUOTE>
A couple of years ago I did some
exploration of the Java Native Interface. At that time, everything "native" was being done in C/C++.
That really wasn't a problem, though, since the syntax of the Java language targets C++ programmers.
(This is clearly evident by the similarities between the two languages.) Now, this isn't to say that Java is identical
to C++ (or unlike other languages for that matter.) It's just an observation of the syntax of the two languages. Also, all of the available
JNI documentation/references were aimed at C/C++ programmers.
<p>
My first go-round with the JNI is documented <a href="http://www.pacifier.com/~mmead/jni/cs510jip/index.html">
here</a>. I basically just presented my findings (albeit, crude.) There wasn't much documentation around at
the time (circa January 1998), so I didn't have too many references. After that initial exposure, I refined
the experiment. That result was more of a tutorial and can be found <A HREF="http://www.cs.pdx.edu/~antoy/Courses/Advanced/units/jni/index.html">
here</a>.
<p>
Since the time of those experiments, I have continued to receive occasional emails from people asking for further assistance. When I was able
to help, I did. Until recently, I hadn't even looked at the JNI stuff. That changed a few weeks ago when I decided to try implementing the
native portion using Borland/Inprise's Delphi language. The result: The acronyms 'JNI' and 'RAD' can now be used in the same sentence. I'm not going
to get into a debate over why one would want to use native code from within Java code, I'm just going to show you how to do it.
Again, this document is aimed specifically at Delphi programmers. C/C++ programmers would want to check out one or both of the links mentioned
above.
<p>
<a href="#Top">Back to top</a>
</BLOCKQUOTE>
<div class="SectionHeader">
<A NAME="Overview">Overview</A>
</div>
<BLOCKQUOTE>
Before starting this, you should be able to compile and execute Java code on your machine. This document focuses on getting you up to speed
with Delphi and the Java Native Interface. I'm not an expert on Java, and setting up and configuring a compile-time and run-time environment
sometimes seems harder than actually writing the Java code (although I think that the Java 2 stuff makes it a little easier.)
<p>
Another important point about this Delphi interface is that it hasn't been tested thoroughly. I present several different "tests" (examples), but
there are over 200 distinct functions in the API of the JNI. I'm probably only using a couple dozen at most. But, you'll see how similar they are. In
fact, 90% of the Delphi interface looks pretty repetitive. Once you get the "pattern" down, you can easily translate any
function's signature. For Part One, though, you shouldn't have any problems because I'm really not using any of the JNI API.
<p>
One last thing: I used version 5.0 of Delphi to develop this. I'm not sure how the other versions will handle it. If I find the time, I will run the
tests through the other versions. (I have all 5 versions of Delphi, I just don't want to spend the time installing/uninstalling them!!) If anyone
tries this with another version, please feel free to let me know how it went.
<p>
<a href="#Top">Back to top</a>
</BLOCKQUOTE>
<div class="SectionHeader">
<A NAME="Translation">Translation Notes</A>
</div>
<BLOCKQUOTE>
<p>
First off, it's important to note that this isn't the only possible translation. As I will show later, you can translate a type incorrectly (loosely speaking),
but as long as the two types have the same size, everything will work. As a preview to this, you'll see a lot of things typed as <tt>Pointer</tt>,
which is very generic, and as far as the JNI is concerned, any type that is exactly 4-bytes wide (at the time of this writing) is compatible with a Delphi pointer.
<p>
Originally, I had planned to explain the <a href="src/jni_pas.html">jni.pas </a> in detail. But, I've decided to leave that for a more advanced topic. It's not
that the translation is advanced (quite the contrary), it's just that it isn't necessary to understand the details to start using the JNI with Delphi, which
I'm assuming is why you're here. I will describe a couple of key points about the translation from C/C++ to Delphi. If you are not interested (and it's
quite alright if you are not interested) you can skip to the <a href="#Example">Example</a> below. If you do wish to know more, you should look at
these:
<ul>
<li><a href="src/jni_pas.html">jni.pas </a> - A Delphi interface to the Java Native Interface.
<li><a href="http://java.sun.com/products/jdk/1.2/docs/guide/jni/index.html"> The JNI Specification</a> - This is Sun's documentation. It's well written
and is considered <i>the</i> authority on the subject. If there is a conflict between what I say and what Sun says, you should follow Sun's advice.
</ul>
<p>
The two most important guidelines when translating a C/C++ header file (interface) is to make sure that:
<ul>
<li>the Delphi type you are mapping to a C/C++ type is the same <i>size</i> as the C/C++ type.
<li>the fields declared in a Delphi <b><tt>record</tt></b> are in the same <i>order</i> as the fields in the corresponding C/C++ <b><tt>struct</tt></b>.
</ul>
<b>Size</b>
<BLOCKQUOTE>
<p>
It is important that the data types that are passed between Java
and native code are the same size. The table below shows this mapping. The types labeled
as <i>Native Type</i> are the types that will be defined in Delphi. This is safer than
trying to remember that a <tt>long</tt> in Java is an <tt>Int64</tt> in Delphi, or that an <tt>int</tt> in Java
is a <tt>Longint</tt> in Delphi. Also, there is no void type in Delphi, but there is a 'void pointer',
<tt>Pointer</tt>, which we will see a lot. This table is not exhaustive. It just shows the primitive
types.
<p>
<blockquote>
<table border=1 cellpadding=4>
<tr>
<td><b>Java Type</b></td><td><b>Delphi Type</b></td><td><b>C++ Type</b></td><td><b>Native Type</b></td><td><b>Description</td></b>
</tr>
<tr>
<td>boolean</td><td>Boolean</td><td>unsigned char</td><td>jboolean</td><td>8 bits, unsigned</td>
</tr>
<tr>
<td>byte</td><td>Shortint</td><td>char</td><td>jbyte</td><td>8 bits, signed</td>
</tr>
<tr>
<td>char</td><td>WideChar</td><td>unsigned short</td><td>jchar</td><td>16 bits, unsigned</td>
</tr>
<tr>
<td>double</td><td>Double</td><td>double</td><td>jdouble</td><td>64 bits</td>
</tr>
<tr>
<td>float</td><td>Single</td><td>float</td><td>jfloat</td><td>32 bits</td>
</tr>
<tr>
<td>int</td><td>Longint</td><td>long</td><td>jint</td><td>32 bits, signed</td>
</tr>
<tr>
<td>long</td><td>Int64</td><td>__int64</td><td>jlong</td><td>64 bits, signed</td>
</tr>
<tr>
<td>short</td><td>Smallint</td><td>short</td><td>jshort</td><td>16 bits, signed</td>
</tr>
<tr>
<td>void</td><td>N/A</td><td>void</td><td>void</td><td>N/A</td>
</tr>
</table>
</blockquote>
<p>
The type definitions below are excerpts from <a href="src/jni_md_pas.html">jni_md.pas</a> and <a href="src/jni_pas.html">jni.pas</a>
which show how Delphi types are mapped into Java types:
<BLOCKQUOTE>
<pre class="sourcecode"><code><b>type</b>
<font color="#003399"><i>(*
* These are Win32-specific types
*)</i></font>
JInt = Integer;
JLong = Int64;
JByte = Shortint;
<font color="#003399"><i>(*
* JNI Types
*)</i></font>
JBoolean = Byte;
JChar = WideChar;
JShort = Smallint;
JFloat = Single;
JDouble = Double;
</code></pre>
</BLOCKQUOTE>
<p>
<b>Preview:</b>
<BLOCKQUOTE>
Here are a couple of Java functions:
<pre class="sourcecode"><code> <b>double</b> CalculateAverage(<b>int</b> A, <b>int</b> B, <b>int</b> C);
<b>void</b> printString(String value);
</code></pre>
and this is how they would appear in Delphi:
<pre class="sourcecode"><code> <b>function</b> CalculateAverage(A: JInt; B: JInt; C: JInt): JDouble;
<b>procedure</b> printString(Value: JString);
</code></pre>
Actually, the functions would look more like this:
<pre class="sourcecode"><code> <b>function</b> Java_Native_CalculateAverage(PEnv: PJNIEnv; Obj: JObject; A: JInt; B: JInt; C: JInt); <b>stdcall</b>;
<b>procedure</b> Java_Native_printString(PEnv: PJNIEnv; Obj: JObject; Value: JString); <b>stdcall</b>;
</code></pre>
but we're not there yet. At this point, it's important that you recognize the correlation between Java types
and Delphi types.
</BLOCKQUOTE>
</BLOCKQUOTE>
<b>Order</b>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -