Sign in Join
Wiki copytemporary

Using Pascal Libraries with Java: what changed

Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.

Title: Using Pascal Libraries with Java

OldNewLine
1+## Introduction
2+
3+Java cannot access "normal" native libraries.
4+
5+## Accessing FPC libraries
6+
7+The easiest way to use your Pascal code from Java is to run the [[pas2jni]] utility which will generate all needed headers and code for you.
8+
9+If your wish to know how to do things manually, check the information below.
10+
11+To access native libraries, Java needs some more arguments. =\> **jni.pas** helps to do it...
12+
13+You may add 2 more arguments for all your functions/procedures:
14+
15+=\> **PEnv: PJNIEnv** as first argument and **Obj: JObject** as second argument.
16+
17+And you have to export the procedures/functions with Java look.
18+
19+Here how may look a fpc library Java compatible:
20+
21+``` pascal
22+library Myfpc4JavaLib;
23+
24+uses
25+ jni
26+
27+procedure proc4java(PEnv: PJNIEnv; Obj: JObject); cdecl;
28+begin
29+ /// your code here
30+end;
31+
32+exports
33+ proc4java name 'Java_Myfpc4JavaLib_proc4java';
34+
35+begin
36+
37+end.
38+```
39+
40+## Dealing with string in Java
41+
42+Here how to translate a Java string into a fpc string:
43+
44+``` pascal
45+function JStringtoString(PEnv: PJNIEnv; Obj: JObject; JavaStr: JString) : String;
46+begin
47+result := (PEnv^^).GetStringUTFChars(PEnv, JavaStr, nil);
48+ (PEnv^^).ReleaseStringUTFChars(PEnv, JavaStr, nil); // release memory to avoid memory leak
49+end;
50+```
51+
52+## Dealing with callback procedures
53+
54+``` pascal
55+library mycallbacklib;
56+
57+uses
58+ jni;
59+
60+...
61+var
62+theclass : JClass; //// => This added to define Java class to use...
63+...
64+
65+procedure JavaInit( PEnv: PJNIEnv; Obj: JObject ; MClass : Jstring); cdecl; // => to find the Java class used...
66+var
67+MainClass : Pchar ;
68+begin
69+ MainClass := (PEnv^^).GetStringUTFChars(PEnv, MClass, nil);
70+ theclass := (PEnv^^).FindClass(PEnv,MainClass) ;
71+ (PEnv^^).ReleaseStringUTFChars(PEnv, MClass, nil);
72+end;
73+
74+procedure libcallback(PEnv: PJNIEnv; Obj: JObject; callback : JString); cdecl;
75+var
76+ theproc : PChar;
77+ theMethod: JMethodID;
78+begin
79+ theproc := (PEnv^^).GetStringUTFChars(PEnv, callback, nil);
80+ theMethod := (PEnv^^).GetStaticMethodID(PEnv, theclass, theproc,'()V'); // theclass was defined with Javainit
81+ (PEnv^^).CallVoidMethod(PEnv,Obj,theMethod) ; // run the callback...
82+ (PEnv^^).ReleaseStringUTFChars(PEnv, callback, nil); // release memory to avoid memory leak
83+end;
84+
85+exports
86+ libcallback name 'Java_MyCallback_libcallback',
87+ JavaInit name 'Java_MyCallback_javainit';
88+
89+begin
90+end.
91+```
92+
93+=\> Java side :
94+
95+``` java
96+public class MyCallback {
97+ public static void javacallback() {
98+ System.out.println("Yep, it works...");
99+ }
100+
101+ public static native void libcallback(String st);
102+ public static native void javainit(String st);
103+
104+
105+ public static void main(String[] args) {
106+ System.loadLibrary("mycallbacklib");
107+ javainit("MyCallback");
108+ libcallback("javacallback");
109+ }
110+}
111+```
112+
113+## Java program example
114+
115+And, finally, a Java program using fpc native Java library and callbacks:
116+
117+``` java
118+public class test {
119+ // The native library declarations. //
120+ public static native void nativemethod1(String t, String cb);
121+ public static native void nativemethod2(int i, int j, String cb);
122+ public static native void nativemethod3(String cb);
123+ public static native void javainit(String st, String cb);
124+
125+ static {
126+ System.loadLibrary("mylib");
127+ }
128+
129+ ...
130+
131+ // The callback methods used by library //
132+ public static void method1() { // callback used by native method1
133+ nativemethod3();
134+ }
135+
136+ public static void method2() { // callback used by native method2
137+ nativemethod1("Hello");
138+ }
139+
140+ public static void method3() { // callback used by native method3
141+ nativemethod1(1,2);
142+ }
143+
144+ ...
145+
146+ // The main application //
147+ public static void main(String[] args) {
148+ javainit("test");
149+ nativemethod1("sometest", "method1");
150+ nativemethod2(1, 2, "method2");
151+ nativemethod3("method3");
152+ ...
153+ }
154+}
155+```
156+
157+## Dealing with threads and synchronize Java method inside threads.
158+
159+It is possible to use threads with your Java compatible fpc library. If you have to synchronize some Java-methods inside the thread, you must call "checksynchronize()" from the main Java class.
160+
161+So, you may add one more procedure into your library :
162+
163+``` pascal
164+library mysynchrolib;
165+
166+uses
167+...
168+ classes, jni;
169+
170+...
171+
172+procedure checksynchro(PEnv: PJNIEnv; Obj: JObject); cdecl;
173+begin
174+ checksynchronize();
175+end;
176+
177+exports
178+...
179+ checksynchro name 'Java_mysynchrolib_checksynchro',
180+...
181+
182+begin
183+end.
184+```
185+
186+And, in main java class, call that checksynchro() procedure, with a Java timer, for example...
187+
188+## The final touch: the Java wrapper class
189+
190+You may create a wrapper class who contents all the declarations of the methods exported by your library.
191+
192+Assuming that your fpc library exports the procedures/functions like that:
193+
194+``` java
195+exports
196+ nativemethod1 name 'Java_TheWrapLib_nativemethod1',
197+ nativemethod1 name 'Java_TheWrapLib_nativemethod2',
198+ nativemethod2 name 'Java_TheWrapLib_nativemethod3';
199+```
200+
201+Here is the look of a wrapper Java class:
202+
203+``` java
204+public class TheWrapLib {
205+// The native library declarations. //
206+public static native void nativemethod1(String t);
207+public static native void nativemethod2(int i, int j);
208+public static native void nativemethod3();
209+static {System.loadLibrary("mylib");}
210+...
211+}
212+```
213+
214+and here how to use that wrapper in the main Java class:
215+
216+``` java
217+public class test {
218+// The main application //
219+public static void main(String[] args)
220+{
221+TheWrapLib.nativemethod1("test");
222+TheWrapLib.nativemethod2(0, 1);
223+TheWrapLib.nativemethod3();
224+...
225+}
226+}
227+```
228+
229+## How to run the main Java class
230+
231+You may run your Java class like this:
232+
233+# \> if library in same folder than main java class
234+
235+\>
236+
237+``` java
238+java -Djava.library.path=. myjavaprogram.java
239+```
240+
241+# \> if library in other folder than main java class
242+
243+\>
244+
245+``` java
246+java -Djava.library.path=/thefolder/iwant/ myjavaprogram.java
247+```
248+
249+---
250+*From the Free Pascal wiki, page "Using Pascal Libraries with Java", as it stood on 2019-12-27 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*
251+Category: FPC
252+Category: Java
253+Category: Other programming languages

Back to history