Sign in Join
Wiki copytemporary

pas2jni: what changed

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

OldNewLine
11# Overview
22
33The **pas2jni** utility generates a JNI (Java Native Interface) bridge for a Pascal code. Then the Pascal code (including classes and other advanced features) can be easily used in Java programs on various platforms, including [[Android]].
44
55For example you can do the following in Java:
66
77``` java
88import pas.classes.*;
99
1010...
1111
1212TStringList sl = TStringList.Create();
1313sl.Add("Hello.");
1414String s = sl.getStrings(0);
1515sl.Free();
1616
1717...
1818```
1919
2020The following Pascal features are supported by **pas2jni**:
2121
2222- function/procedure;
2323- var/out parameters;
2424- class;
2525- interface;
2626- object;
2727- record;
2828- property;
2929- constant;
3030- enum;
3131- set (32 elements maximum);
3232- TGuid type;
3333- pointer type;
3434- string types;
3535- all numeric types;
3636- method pointer;
3737- array (limited support: setters/getters for array elements).
3838
3939**USUPPORTED features:**
4040
4141- array (full support);
4242- set (with 32+ elements);
4343- procedure pointer (Not possible to implement. To workaround this limitation create a procedure handler in your Pascal code and call a method pointer declared in some global Pascal class. Then you can assign this method pointer from a Java code).
4444
4545Shared libraries, generated by pas2jni were tested with Java on Windows and Android. It should work on other systems as well.
4646
4747# How to use
4848
4949**pas2jni** uses the [[PPUDump]] utility included with Free Pascal Compiler to read unit interfaces. Therefore your Pascal code must be first compiled with FPC. When your units are compiled, you can run **pas2jni**. You need to specify a list of main units and units search path. When you specify a main unit, all its interface declarations will be available in Java. For linked units only used declarations will be available. You can fine tune included/excluded declaration using `-I` and `-E` command line options.
5050
5151The basic invocation of **pas2jni**:
5252
53-`pas2jni myunit -U/path/to/my/units;/path/to/FPC/units/*`
53+```text
54+pas2jni myunit -U/path/to/my/units;/path/to/FPC/units/*
55+```
5456
5557Here you specify myunit as the main unit and provide path to your compiled units and FPC compiled units.
5658
5759After successfull run of **pas2jni** you will get the following output files:
5860
5961- file **`myunitjni.pas`** - a generated library unit to be compiled to a shared library. It will contain all your Pascal code to be used from Java.
6062- folder **`pas`** - generated Java package **`pas`** to be used in your Java program. Interface to each Pascal unit is placed to a separate Java public class.
6163
6264Note: You need to use **ppudump** of the same version as the FPC compiler. Use the `-D` switch to specify correct **ppudump** if it is not in `PATH`.
6365
6466# Custom handlers
6567
6668It is possible to define the following custom handlers in your Pascal code.
6769
6870**`procedure JNI_OnException;`**
6971
7072- It is called when an unhandled Pascal exception occurs. For example, you can log a stack back trace in this handler.
7173
7274Custom handlers must be public and defined in one of the main units specified when calling **pas2jni**.
7375
7476# Coding tips
7577
7678## Setting handlers (method pointers) in a Java code.
7779
7880For example there is the following class and event handler in your Pascal code:
7981
8082``` pascal
8183type TMyClass = class
8284//...
8385 property OnChange: TNotifyEvent;
8486//...
8587end;
8688```
8789
8890In Java code, you add the event handler in a usual Java way:
8991
9092``` java
9193// Create an instance of TMyClass
9294TMyClass myClass = TMyClass.Create();
9395
9496// Set the event handler
9597myClass.setOnChange(
9698 new TNotifyEvent() {
9799 protected void Execute(TObject Sender) {
98100 // The handler code
99101 }
100102 }
101103 );
102104
103105// Work with myClass
104106// ...
105107// ...
106108
107109// Remove the handler to avoid memory leak
108110myClass.setOnChange(null);
109111// Free the object
110112myClass.Free();
111113```
112114
113115NOTE: If you are setting handlers (method pointers) for short living objects, it is needed to explicitly remove the handlers before the object destruction by setting the **null handler**. Otherwise you will reach the active handlers limit (10000 handlers) and your application will crash.
114116
115117## Type casting
116118
117119In some cases type casting for generated Java classes does not work as expected. For example, the following code will not compile:
118120
119121``` java
120122contnrs.TObjectList objList = contnrs.TObjectList.Create();
121123classes.TList list = objList;
122124```
123125
124126Though `TObjectList` is inherited from `TList` and similar code works in Pascal, the generated Java classes use a bit different class hierarchy in this case. An intermediate class `__TList` is used and `TList` is not ancestor for `TObjectList` anymore. The `__TList` class is needed to handle method reintroducing, which is allowed in Pascal, but not allowed in Java.
125127
126128You need to use the following type casting trick in such case:
127129
128130``` java
129131classes.TList list = new classes.TList(objList);
130132```
131133
132134The same type casting method is used to cast a pointer to an object:
133135
134136``` java
135137// Create a list
136138classes.TList list = classes.TList.Create();
137139// Get a pointer to the list
138140long pList = system.Pointer(list);
139141// Type cast the pointer to the new TObject variable
140142system.TObject list2 = new system.TObject(pList);
141143```
142144
143145## Passing Java objects to Pascal code
144146
145147In some cases it is needed to pass native Java objects to your Pascal code and handle them directly using JNI functions. For example, you can pass a Java array to your Pascal code to perform some quick processing of the array's data.
146148
147149To do that you need to use a specially defined type `TJavaObject`. Use this type for function parameters to indicate that this parameter expect a Java object without any special processing.
148150
149151Also it is needed a pointer to the JNI environment in order to call JNI functions. Just add a parameter of type `PJNIEnv` to access the JNI environment using this parameter.
150152
151153Here an example:
152154
153155``` pascal
154156// Define a special type TJavaObject. The declaration must be exactly as shown here
155157type
156158 TJavaObject = type jobject;
157159
158160// Define your procedure
159161procedure HandleJavaObject(env: PJNIEnv; obj: TJavaObject; myParam: longint);
160162begin
161163 // Work with native Java object 'obj' using JNI functions accessible via 'env'.
162164 // ...
163165end;
164166```
165167
166168You will get the following generated declaration in Java for this procedure:
167169
168170``` java
169171public native static void HandleJavaObject(Object obj, int myParam);
170172```
171173
172174# Command line options
173175
174176 Usage: pas2jni [options] <unit> [<unit2> <unit3> ...]
175177
176178 Options:
177179 -U<path> - Unit search path, semicolon delimited. Wildcards are allowed.
178180 -L<name> - Set output library name.
179181 -P<name> - Set Java package name.
180182 -O<path> - Set output path for Pascal files.
181183 -J<path> - Set output path for Java files.
182184 -D<prog> - Set full path to the "ppudump" program.
183185 -I<list> - Include the list of specified objects in the output. The list is
184186 semicolon delimited. To read the list from a file use -I@<file>
185187 -E<list> - Exclude the list of specified objects from the output. The list is
186188 semicolon delimited. To read the list from a file use -E@<file>
187189 -? - Show this help information.
188190
189191---
190192*From the Free Pascal wiki, page "pas2jni", as it stood on 2020-01-29 after a change by Yurysidorov, 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).*
191193Category: FPC
192194Category: Utilities

Back to history