📄 native_dpr.html
字号:
<font color="#003399"><i>// Print each element, then multiply the Value by 10</i></font>
<font color="#003399"><i>// and put it back into the array. (This is to prove that</i></font>
<font color="#003399"><i>// the array elements have changed when this function returns</i></font>
<font color="#003399"><i>// to Java code.</i></font>
<b>for</b> J := 0 <b>to</b> Len - 1 <b>do</b>
<b>begin</b>
WriteLn(Format(<font color="#9933CC">'%d,%d = %d'</font>, [I, J, Elements^]));
<font color="#003399"><i>// Update the element (just multiply it by 10)</i></font>
Elements^ := Elements^ * 10;
Inc(Elements);
<b>end</b>;
<b>end</b>;
JVM.Free;
<b>end</b>;
<font color="#003399"><i>(****************************************************************************
* This is a sample algorithm that I got from Microsoft's documentation.
* I used it as the initial test case. I may have modified it slightly.
*
* The interesting point in this example is that the function is declared
* as 'static' in the Java code. The only difference at the native level
* is that the second parameter is a 'JClass' instead of a 'JObject'.
* Most functions are non-static, and so require a handle to the object
* rather than the class.
*
* Java declaration:
* native public static int countPrimes(byte[] array);
*
* Class: Native
* Method: countPrimes
* Signature: ([B)I
*)</i></font>
<b>function</b> Java_Native_countPrimes(PEnv: PJNIEnv; Cls: JClass; ByteArray: JByteArray): JInt; <b>stdcall</b>;
<b>var</b>
Count, Len: ULONG;
I, J: ULONG;
Body: PJByte;
IsCopy: JBoolean;
Ptr: PChar;
JVM: TJNIEnv;
<b>begin</b>
<font color="#003399"><i>// Create an instance of the Java environment</i></font>
JVM := TJNIEnv.Create(PEnv);
<font color="#003399"><i>// Get the length of the array</i></font>
Len := JVM.GetArrayLength(ByteArray);
<font color="#003399"><i>// Get a pointer to the elements of the array. Only primitive elements</i></font>
<font color="#003399"><i>// can be accessed this way.</i></font>
Body := JVM.GetByteArrayElements(ByteArray, IsCopy);
<font color="#003399"><i>// Since body is not a Delphi array (Body is of type PJByte), we need to use</i></font>
<font color="#003399"><i>// a PChar (interchangeable with arrays) to access the java array using an</i></font>
<font color="#003399"><i>// index (e.g. Body[0] is illegal, but Ptr[0] is legal)</i></font>
Ptr := PChar(Body);
<font color="#003399"><i>// Initialize all elements</i></font>
<b>for</b> I := 0 <b>to</b> Len - 1 <b>do</b>
Ptr[i] := #1;
Count := 0;
<font color="#003399"><i>// Set each element at a non-prime index to 0</i></font>
<b>for</b> I := 2 <b>to</b> Len - 1 <b>do</b>
<b>begin</b>
<b>if</b> Ptr[I] <> #0 <b>then</b>
<b>begin</b>
J := I + I;
<b>while</b> J < len <b>do</b>
<b>begin</b>
Ptr[J] := #0;
Inc(J, I);
<b>end</b>;
Inc(Count);
<b>end</b>;
<b>end</b>;
<font color="#003399"><i>// The number of primes between 1 and array.length</i></font>
Result := Count;
<b>end</b>;
<font color="#003399"><i>(****************************************************************************
* Java declaration:
* native public void VoidVoid();
*
* This function takes no arguments and returns nothing. Just used to
* demonstrate the most simplistic function call. Also used to time
* function call overhead in the simplest case.
*
* Class: Native
* Method: VoidVoid
* Signature: ()V
*)</i></font>
<b>procedure</b> Java_Native_VoidVoid(PEnv: PJNIEnv; Obj: JObject); <b>stdcall</b>;
<font color="#003399"><i>//var</i></font>
<font color="#003399"><i>//JVM: TJNIEnv;</i></font>
<b>begin</b>
<font color="#003399"><i>// These two lines of code take about 1 ms to execute on a PIII 450 MHz</i></font>
<font color="#003399"><i>//JVM := TJNIEnv.Create(PEnv);</i></font>
<font color="#003399"><i>//JVM.Free;</i></font>
<b>end</b>;
<font color="#003399"><i>(****************************************************************************
* A private native function that calls back into Java. Calls a void
* function just for timings.
*
* Class: Native
* Method: callbackVoid
* Signature: (I)V
*)</i></font>
<b>procedure</b> Java_Native_callbackVoid(PEnv: PJNIEnv; Obj: JObject; Count: JInt); <b>stdcall</b>;
<b>var</b>
Cls: JClass;
Mid: JMethodID;
I: JInt;
JVM: TJNIEnv;
<b>begin</b>
<font color="#003399"><i>// Create an instance of the Java environment</i></font>
JVM := TJNIEnv.Create(PEnv);
<font color="#003399"><i>// Get the class that this object belongs to</i></font>
Cls := JVM.GetObjectClass(Obj);
<font color="#003399"><i>// Get the method ID for 'void voidFunc()'</i></font>
Mid := JVM.GetMethodID(Cls, <font color="#9933CC">'voidFunc'</font>, <font color="#9933CC">'()V'</font>);
<font color="#003399"><i>// If we can't find the ID, just return. This kind of check should be in all</i></font>
<font color="#003399"><i>// functions in this code, but it isn't (for brevity)</i></font>
<b>if</b> (Mid = <b>nil</b>) <b>then</b>
exit;
<font color="#003399"><i>// Perform the callbacks</i></font>
<b>for</b> I := 0 <b>to</b> Count - 1 <b>do</b>
JVM.CallVoidMethodA(Obj, Mid, <b>nil</b>);
<b>end</b>;
<font color="#003399"><i>(****************************************************************************
* Java declaration:
* native public void printVersion();
*
* Prints the version of the JDK being used.
*
* Class: Native
* Method: printVersion
* Signature: ()V
*)</i></font>
<b>procedure</b> Java_Native_printVersion(PEnv: PJNIEnv; Obj: JObject); <b>stdcall</b>;
<b>var</b>
JVM: TJNIEnv;
Major, Minor: JInt;
<b>begin</b>
JVM := TJNIEnv.Create(PEnv);
Major := JVM.MajorVersion;
Minor := JVM.MinorVersion;
WriteLn(Format(<font color="#9933CC">'The Java version is %d.%d'</font>, [Major, Minor]));
<b>end</b>;
<font color="#003399"><i>(****************************************************************************
* Java declaration:
* native public void testAllTypesD();
*
* Tests all data types. Shows how floats passed in open arrays to JNI
* methods are not handled correctly.
*
* Class: Native
* Method: testAllTypesD
* Signature: (ZBCIJFD)V
*)</i></font>
<b>procedure</b> Java_Native_testAllTypesD(PEnv: PJNIEnv; Obj: JObject; Bool: JBoolean; B: JByte; C: JChar; I: JInt; L: JLong; F: jfloat; D: jdouble); <b>stdcall</b>;
<b>var</b>
Cls: JClass;
Mid: JMethodID;
JVM: TJNIEnv;
<b>begin</b>
<font color="#003399"><i>// Create an instance of the Java environment</i></font>
JVM := TJNIEnv.Create(PEnv);
<font color="#003399"><i>// Get the class associated with this object</i></font>
Cls := JVM.GetObjectClass(Obj);
<font color="#003399"><i>// The ID for the testAllTypes method</i></font>
Mid := JVM.GetMethodID(Cls, <font color="#9933CC">'testAllTypes'</font>, <font color="#9933CC">'(ZBCIJFD)V'</font>);
<font color="#003399"><i>// Call it</i></font>
JVM.CallVoidMethod(Obj, Mid, [Bool, B, C, I, L, F, D]);
<b>end</b>;
<font color="#003399"><i>(****************************************************************************
* Java declaration:
* native public void multiplyIntegers(int op1, int op2);
*
* Multiplies 2 integers and returns the result.
*
* Class: Native
* Method: multiplyIntegers
* Signature: (II)I
*)</i></font>
<b>function</b> Java_Native_multiplyIntegers(PEnv: PJNIEnv; Obj: JObject; Op1: JInt; Op2: JInt): jint; <b>stdcall</b>;
<b>begin</b>
Result := Op1 * Op2;
<b>end</b>;
<font color="#003399"><i>(****************************************************************************
* Java declaration:
* native public void initializeByteArrayOnce(byte[] byteArray, byte Value);
*
* Initializes each element of an array with the value 'Value'. This function
* is an overloaded version of the one used to test performance.
*
* Class: Native
* Method: initializeByteArrayOnce
* Signature: ([BB)V
*)</i></font>
<b>procedure</b> Java_Native_initializeByteArray(PEnv: PJNIEnv; Obj: JObject; ByteArray: JByteArray; Value: JByte); <b>stdcall</b>; overload;
<b>var</b>
Elements: PJByte;
PE: PJByte;
Len: DWORD;
I: Longint;
IsCopy: JBoolean;
JVM: TJNIEnv;
<b>begin</b>
<font color="#003399"><i>// Create an instance of the Java environment</i></font>
JVM := TJNIEnv.Create(PEnv);
<font color="#003399"><i>// Get elements of the array.</i></font>
elements := JVM.GetByteArrayElements(ByteArray, IsCopy);
<font color="#003399"><i>// Get length of the array.</i></font>
Len := JVM.GetArrayLength(ByteArray);
<font color="#003399"><i>// Assign 'Value' to each element.</i></font>
PE := Elements;
<b>for</b> I := 0 <b>to</b> Len - 1 <b>do</b>
<b>begin</b>
PE^ := Value;
Inc(PE);
<b>end</b>;
<font color="#003399"><i>// Release the elements of the array.</i></font>
JVM.ReleaseByteArrayElements(ByteArray, Elements, 0);
JVM.Free;
<b>end</b>;
<font color="#003399"><i>(*******************************************************************************
Make these routines available to Java.
*******************************************************************************)</i></font>
<b>exports</b>
Java_Native_initializeByteArray(PEnv: PJNIEnv; Obj: JObject; ByteArray: JByteArray; Count: JInt; Value: JByte)name <font color="#9933CC">'Java_Native_initializeByteArray'</font>,
Java_Native_initializeByteArray(PEnv: PJNIEnv; Obj: JObject; ByteArray: JByteArray; Value: JByte)name <font color="#9933CC">'Java_Native_initializeByteArrayOnce'</font>,
Java_Native_callbackVoid,
Java_Native_causeException,
Java_Native_countPrimes,
Java_Native_displayHelloWorld,
Java_Native_handleException,
Java_Native_multiplyIntegers,
Java_Native_pass2DByteArray,
Java_Native_printLine,
Java_Native_printObjectArray,
Java_Native_printVersion,
Java_Native_printWXYZ,
Java_Native_returnRectArray,
Java_Native_testAllTypesD,
Java_Native_toStringWithPrint,
Java_Native_VoidVoid;
<b>begin</b>
<b>end</b>.
</code></pre>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -