Difference between revisions of "Using Pascal Libraries with Java"

From Free Pascal wiki
Jump to navigationJump to search
(moved java specific stuff to separate page so as not to confuse people regarding fpc librareis)
 
Line 31: Line 31:
 
function JStringtoString(PEnv: PJNIEnv; Obj: JObject; JavaStr: JString) : String;
 
function JStringtoString(PEnv: PJNIEnv; Obj: JObject; JavaStr: JString) : String;
 
begin
 
begin
result  := (PEnv^).GetStringUTFChars(PEnv, JavaStr, nil);
+
result  := (PEnv^^).GetStringUTFChars(PEnv, JavaStr, nil);
 +
(PEnv^^).ReleaseStringUTFChars(PEnv, JavaStr, nil); // release memory to avoid memory leak
 
end;  
 
end;  
 
</syntaxhighlight>
 
</syntaxhighlight>

Revision as of 22:11, 15 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); cdecl;
var
  theclass : JClass;
  theproc  : PChar;
  theMethod: JMethodID;
begin
  theproc := (PEnv^^).GetStringUTFChars(PEnv, 'callback', nil);
  theMethod := (PEnv^^).GetStaticMethodID(PEnv, theclass, theproc,'()V')  ;
  (PEnv^^).CallVoidMethod(PEnv,Obj,theMethod) ; // run the callback...
end;

exports
  libcallback name 'Java_MyCallback_libcallback', 
  JavaInit name 'Java_MyCallback_javainit';

begin
end.

=> Java side :

public class MyCallback {
  public static void callback() {
    System.out.println("Yep, it works...");
  }
  
  public static native void libcallback();
  public static native void javainit(String st); 
 
   
  public static void main(String[] args) {
    System.loadLibrary("mycallbacklib");
    javainit("MyCallback");
    libcallback();
  }
}


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);
  public static native void nativemethod2(int i, int j);
  public static native void nativemethod3();
  public static native void javainit(String st); 
  
  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();
    nativemethod2();
    nativemethod3();
    ...
  }
}