Difference between revisions of "Using Pascal Libraries with Java"

From Lazarus wiki
Jump to navigationJump to search
Line 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();
...
}
}