Java空間

          Java空間
          posts - 1, comments - 0, trackbacks - 0, articles - 0
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          Delphi-JNI-Java Example

          Posted on 2009-09-29 16:18 hanfi 閱讀(1117) 評論(0)  編輯  收藏

          Delphi-JNI-Java Example


          Downloads
          Updated JNI.pas file
          SimpleDemo.zip example
          screenshot.zip example

          official JNI.pas home page
          JavaToDPR tool

          Links
          JNI specs
          CodeGuru JNI tips
          Turbo Delphi IDE

          Java Native Interface is a standard programming interface for writing Java native methods. It is known to be a gray area not so many do and is perfectly fine not to develop .dll/.so libraries. After all, it's just one line away from the JVM crash if not done properly.

          Most JNI developers use C/C++ environment, Sun releases header files only in C format. But Delphi (Object Pascal) has a very active community and JNI headers have been ported for us. Delphi JNI.pas home page hosts an excellent examples and JNI.pas file.

          Use JavaToDPR tool to create MyDelphi.dpr project file from .java source code. It creates all necessary function declarations from native tagged java functions. It simplifies .dll process to automate tedious mandatory JNI function naming convention.

          Enhanced JNI.pas
          Updated JNI.pas file
          Changes are very simple and does not modify anything from the earlier versions.

          • JStringToWideString: convert jstring to widestring
          • WideStringToJString: convert widestring to jstring
          • BytesToJByteArray: convert byte array to JByteArray
          • IntegersToJIntArray: convert integer array to JIntArray
          • ThrowException: wrap native exception to java.lang.Exception
          • SetIntMethod: call public void myClass.setInt(int id) method
          • SetStringMethod: call public void myClass.setString(String s) method
          Enhanced version is not found from the official JNI.pas home page. I have contacted the owner of the version to discuss whether he sees any interest to update the official version.

           

          Java has no problems using unicode strings because the internal format is unicode already. This is not so easy in native side where you have a choice of several string types. Old legacy string is ansistring and unicode-aware is widestring variable type. If you want to send strings back and fort you should keep values in widestring variable. Knowing characters are within the range of system-default encoding you may use ansistring. But doing things right at the year +2006, you should stick to widestring variables.

          SimpleDemo example
          SimpleDemo.zip example (uses enhanced JNI.pas)
          My goal was a short and simple Delphi study.

          • unicode string interchange between Java and Delphi program
          • simple integer interchange between Java and Delphi program
          • Java class instantiation and "setter" methods from Delphi program
          Final conclusion is.....it's not anything magic or too complicated.

           

          Test program calls several native functions and print results to UTF-8 formatted html file. Web browsers have a good unicode support, so character results can be see easily. Verify SimpleDemo.png image what you should see in SimpleDemo.html page generated by test program.

          You need a good unicode font, some Windows has "Arial Unicode MS" which usually works fine. Its installed by some MS software (MSOffice, ...).

          See more info in SimpleDemo.zip/readme.txt file about how to compile project.

          ScreenShot example
          screenshot.zip example (uses enhanced JNI.pas)
          Use native code to take a screenshot from the desktop. Code is able to "see" alphablended windows unlike Java Robot sceenshot method. Example introduces the following technique.

          • return byte array from Delphi to Java
          • return integer array from Delphi to Java

           

          Turbo Delphi
          Turbo Delphi IDE
          Turbo Delphi is a new release from Borland Delphi. Now you can get one of the best win32 development tool reasonable price....or even free of charge. Turbo Delphi Professional version provides a cutting edge version.
          The free Turbo Delphi Explorer edition lets beginners and hobbyists learn win32 programming. But you can install only one Explorer version to the same machine, so be sure to take your favourite version. This page goes for Delphi release of course.


          SimpleDemo example: Java and Delphi code
          Java class has one or more native method declarations, that are implemented in .dll library. Java program may use functions just like any other pure Java functions.

          You need three files in this example:
          SimpleDemo.java, SimpleDemo.dpr, uSimpleDemo.pas

          file: SimpleDemo.java
          public class SimpleDemo {
          public static void main(String[] args) throws Exception {
          // call native Delphi method from Java
          SimpleDemo sd = new SimpleDemo();
          System.out.println( sd.getStringDelphiJ("Hello from Java") );
          }
          // declare native functions
          native public String getStringDelphiJ(String s);
          // load .dll library at startup
          static {
          System.loadLibrary("SimpleDemo");
          }
          }
          

          Native Delphi side few extra jumps to implement functions. Use JavaToDPR tool to create .dpr project file with all necessary function declarations, then implement function skeletons.
          • Declare library SimpleDemo; to compile SimpleDemo.dll file
          • import JNI.pas; file, that implements JNI interface
          • declare and implement native public String getStringDelphiJ(String s); method
          • function must use a strict naming convention
            Java_ prefix is mandatory for each jni entrypoint method
            package_classname_ from java class, this example does not have a package in a .java source file, so its just classname.
            functionname from java class
            PEnv: PJNIEnv; Obj:JObject args are always present
            optional params if java method declared any
          Java uses unicode for internal strings, so you should convert string function arguments and/or function return values to WideString. If you don't, use risk losing 100% international aware programming. This example uses a helper methods to convert back and fort java strings and native widestrings.
          file: SimpleDemo.dpr
          library SimpleDemo;
          // import JNI.pas file
          uses
          SysUtils,
          uSimpleDemo in 'uSimpleDemo.pas',
          JNI in '..\..\JNI\JNI.pas';
          {$R *.res}
          function Java_SimpleDemo_getStringDelphiJ
          (PEnv: PJNIEnv; Obj: JObject; Arg1: JString): JString; stdcall;
          begin
          // - convert JNI-JString to Widestring (unicode)
          // - call uSimpleDemo.getStringDelphiJ(s: Widestring) method
          // - convert widestring to JNI-JString
          // - return JNI-String back to java program
          // try-catch all exceptions and wrap it to
          // to java.lang.Exception
          try
          Result := JNI_WideStringToJString(PEnv,
          uSimpleDemo.getStringDelphiJ(
          JNI_JStringToWideString(PEnv, Arg1)
          )
          );
          except
          on E: Exception do begin
          Result := nil;
          JNI_ThrowException(PEnv, E);
          end;
          end;
          end;
          exports
          // export public JNI .dll functions
          Java_SimpleDemo_getStringDelphiJ;
          end.
          

          It's a good practice to write implementations to another unit file, and keep just necessary JNI interface stuff in SimpleDemo.dpr project file.
          file: uSimpleDemo.pas
          unit uSimpleDemo; interface // declare public functions function getStringDelphiJ(ws: WideString): WideString; forward; implementation uses SysUtils; // implement function function getStringDelphiJ(ws: WideString): WideString; var ws2: WideString; begin ws2 := WideUpperCase(ws); Result := 'Uppercased in dll: ' + ws2 + ' (len ' + IntToStr(Length(ws2)) + ')'; end; end.

           


          Last update 2006-09-12 20:40

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 健康| 当雄县| 房产| 锡林浩特市| 永登县| 梓潼县| 阳城县| 黔西| 来凤县| 鸡泽县| 东乌珠穆沁旗| 宜兰市| 永吉县| 肥城市| 沈丘县| 西华县| 无棣县| 资兴市| 会宁县| 微博| 石景山区| 阿拉善右旗| 杭锦后旗| 夏邑县| 余姚市| 吴旗县| 江北区| 五莲县| 巴马| 安丘市| 尖扎县| 东明县| 永仁县| 慈利县| 青河县| 都昌县| 郴州市| 泸定县| 洛南县| 平塘县| 西和县|