Difference between revisions of "Using Pascal Libraries with Java"
From Free Pascal wiki
Jump to navigationJump to searchLine 138: | Line 138: | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | == The final touch: the Java wrapper class == | ||
+ | |||
+ | You may create a wrapper class who contents all the declarations of the methods exported by your library. | ||
+ | Here is the look of a wrapper Java class: | ||
+ | <syntaxhighlight lang="java"> | ||
+ | public class TheWrapper { | ||
+ | // The native library declarations. // | ||
+ | public static native void nativemethod1(String t); | ||
+ | public static native void nativemethod2(int i, int j); | ||
+ | public static native void nativemethod3(); | ||
+ | static {System.loadLibrary("mylib");} | ||
+ | ... | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | and here how to use that wrapper in the main Java class: | ||
+ | |||
+ | <syntaxhighlight lang="java"> | ||
+ | public class test { | ||
+ | // The main application // | ||
+ | public static void main(String[] args) | ||
+ | { | ||
+ | TheWrapper.nativemethod1(); | ||
+ | TheWrapper.nativemethod2(); | ||
+ | TheWrapper.nativemethod3(); | ||
+ | ... | ||
+ | } | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
[[Category:Other programming languages]] | [[Category:Other programming languages]] | ||
[[Category:FPC]] | [[Category:FPC]] | ||
[[Category:Java]] | [[Category:Java]] |
Revision as of 13:30, 28 April 2014
Introduction
Java cannot access "normal" native libraries.
Accessing FPC libraries
To access native libraries, Java needs some more arguments. => jni.pas helps to do it...
You may add 2 more arguments for all your functions/procedures:
=> PEnv: PJNIEnv as first argument and Obj: JObject as second argument.
And you have to export the procedures/functions with Java look.
Here how may look a fpc library Java compatible:
library Myfpc4JavaLib;
uses
jni
procedure proc4java(PEnv: PJNIEnv; Obj: JObject); cdecl;
begin
/// your stufs..
end;
exports
proc4java name 'Java_Myfpc4JavaLib_proc4java' ;
begin
end.
Dealing with string in Java
Here how to translate a Java string into a fpc string:
function JStringtoString(PEnv: PJNIEnv; Obj: JObject; JavaStr: JString) : String;
begin
result := (PEnv^^).GetStringUTFChars(PEnv, JavaStr, nil);
(PEnv^^).ReleaseStringUTFChars(PEnv, JavaStr, nil); // release memory to avoid memory leak
end;
Dealing with callback procedures
library mycallbacklib;
uses
jni;
...
var
theclass : JClass; //// => This added to define Java class to use...
...
procedure JavaInit( PEnv: PJNIEnv; Obj: JObject ; MClass : Jstring); cdecl; // => to find the Java class used...
var
MainClass : Pchar ;
begin
MainClass := (PEnv^^).GetStringUTFChars(PEnv, MClass, nil);
theclass := (PEnv^^).FindClass(PEnv,MainClass) ;
(PEnv^^).ReleaseStringUTFChars(PEnv, MClass, nil);
end;
procedure libcallback(PEnv: PJNIEnv; Obj: JObject; callback : JString); cdecl;
var
theproc : PChar;
theMethod: JMethodID;
begin
theproc := (PEnv^^).GetStringUTFChars(PEnv, callback, nil);
theMethod := (PEnv^^).GetStaticMethodID(PEnv, theclass, theproc,'()V'); // theclass was defined with Javainit
(PEnv^^).CallVoidMethod(PEnv,Obj,theMethod) ; // run the callback...
(PEnv^^).ReleaseStringUTFChars(PEnv, callback, nil); // release memory to avoid memory leak
end;
exports
libcallback name 'Java_MyCallback_libcallback',
JavaInit name 'Java_MyCallback_javainit';
begin
end.
=> Java side :
public class MyCallback {
public static void javacallback() {
System.out.println("Yep, it works...");
}
public static native void libcallback(String st);
public static native void javainit(String st);
public static void main(String[] args) {
System.loadLibrary("mycallbacklib");
javainit("MyCallback");
libcallback("javacallback");
}
}
Java program example
And, finally, a Java program using fpc native Java library and callbacks:
public class test {
// The native library declarations. //
public static native void nativemethod1(String t, String cb);
public static native void nativemethod2(int i, int j, String cb);
public static native void nativemethod3(String cb);
public static native void javainit(String st, String cb);
static {
System.loadLibrary("mylib");
}
...
// The callback methods used by library //
public static void method1() { // callback used by native method1
nativemethod3();
}
public static void method2() { // callback used by native method2
nativemethod1("Hello");
}
public static void method3() { // callback used by native method3
nativemethod1(1,2);
}
...
// The main application //
public static void main(String[] args) {
javainit("test");
nativemethod1("sometest", "method1");
nativemethod2(1, 2, "method2");
nativemethod3("method3");
...
}
}
The final touch: the Java wrapper class
You may create a wrapper class who contents all the declarations of the methods exported by your library. Here is the look of a wrapper Java class:
public class TheWrapper {
// The native library declarations. //
public static native void nativemethod1(String t);
public static native void nativemethod2(int i, int j);
public static native void nativemethod3();
static {System.loadLibrary("mylib");}
...
}
and here how to use that wrapper in the main Java class:
public class test {
// The main application //
public static void main(String[] args)
{
TheWrapper.nativemethod1();
TheWrapper.nativemethod2();
TheWrapper.nativemethod3();
...
}
}