310 likes | 458 Views
ScriptBasic külső modulok kezelése, összehasonlítás más alkalmazásokkal. Peter Verh á s 2002 március 26. Tartalom. Java programozás kiterjesztése JNI felülettel Perl XS modulok PHP külső modulok. JNI: Java Native Interface.
E N D
ScriptBasic külső modulok kezelése, összehasonlítás más alkalmazásokkal Peter Verhás 2002 március 26.
Tartalom • Java programozás kiterjesztése JNI felülettel • Perl XS modulok • PHP külső modulok
JNI: Java Native Interface http://java.sun.com/docs/books/tutorial/native1.1/concepts/index.html A Java nyelvhez lehet C nyelven programokat írni ennek a felületnek a felhasználásával. JRE JNI modul.dll
JNI modul írásának lépései • Java program írásával kell kezdeni. A Java osztályt kell létrehozni, amelyik deklarálja a natív függvényeket, és a main metódust, amelyik meghívja majd a natív függvényt. • Lefordítjuk a Java osztályt a javac fordítóval. • A javah –jniprogrammallétrehozzuk a C fejléc fájlt. Ebben benne van a függvények prototípusa. • Implementáljuk C-ben a függvényeket. • Lefordítjuk a függvényeket DLL-be (vagy SO-ba) • Futtatjuk a Java programot.
Példa: halló világ class HelloWorld { public native void displayHelloWorld(); static { System.loadLibrary("hello"); } public static void main(String[] args) { new HelloWorld().displayHelloWorld(); } }
javah -jni /* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class HelloWorld */ #ifndef _Included_HelloWorld #define _Included_HelloWorld #ifdef __cplusplus extern "C" { #endif /* * Class: HelloWorld * Method: displayHelloWorld * Signature: ()V */ JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif
Név dekoráció Java_HelloWorld_displayHelloWorld • Javaprefix • HelloWorld osztály név • displayHelloWorld metódus név
Paraméterek JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld (JNIEnv *, jobject); • JNIEnv futtatási környezet • jobjectaz aktuális objektum
Implementált C kód #include <jni.h> #include "HelloWorld.h" #include <stdio.h> JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld (JNIEnv *env, jobject obj) { printf("Hello world!\n"); return; }
Második példa: getsLine • Java kód class Prompt { private native String getLine(String prompt); public static void main(String args[]) { Prompt p = new Prompt(); String input = p.getLine("Type a line: "); System.out.println("User typed: " + input); } static { System.loadLibrary("MyImpOfPrompt"); } }
C kód JNIEXPORT jstring JNICALL Java_Prompt_getLine(JNIEnv *env, jobject obj, jstring prompt) { char buf[128]; const char *str = (*env)->GetStringUTFChars(env, prompt, 0); printf("%s", str); (*env)->ReleaseStringUTFChars(env, prompt, str); ...
Második példa: getLine, getLine2 • Java kód: class Prompt2 { private native String getLine(String prompt); private native String getLine(String prompt, int length); public static void main(String args[]) { Prompt2 p = new Prompt2(); String input = p.getLine("Type a line: "); System.out.println("User typed: " + input); } static { System.loadLibrary("MyImpOfPrompt2"); } }
Név dekoráció /* * Class: Prompt2 * Method: getLine * Signature: (Ljava/lang/String;)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_Prompt2_getLine__Ljava_lang_String_2 (JNIEnv *, jobject, jstring); /* * Class: Prompt2 * Method: getLine * Signature: (Ljava/lang/String;I)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_Prompt2_getLine__Ljava_lang_String_2I (JNIEnv *, jobject, jstring, jint);
Mit tehet egy JNI függvény? • Java füzér kezelés • Java tömb kezelés • Java metódusok meghívása • Java változó kezelése (név dekoráció) • Kivételkezelés • ...
JNI összefoglaló • Függvény név kötött, függ a többi függvénytől (overload) • Nincs boot/finish függvény (legyen Java szinten kezelve) • Nincs statikus linkelés
Perl külső függvények írása • Speciális XS nyelven, ami C kiterjesztés • XS -> C fordító
Demó XS készítése • h2xs -A -n Mytest • Elkészít minden szükséges alap fájlt • Mytest.xs • Makefile.PL • Mytest.pm
Mytest.xs #include "EXTERN.h" #include "perl.h" #include "XSUB.h" MODULE = Mytest PACKAGE = Mytest void hello() CODE: printf("hello");
Az XS-ből generált C fájl 1/3 /* * This file was generated automatically by xsubpp version 1.9508 from the * contents of Mytest.xs. Do not edit this file, edit Mytest.xs instead. * * ANY CHANGES MADE HERE WILL BE LOST! * */ #line 1 "Mytest.xs" #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #line 16 "Mytest.c"
Az XS-ből generált C fájl 2/3 XS(XS_Mytest_hello) { dXSARGS; if (items != 0) Perl_croak(aTHX_ "Usage: Mytest::hello()"); { #line 11 "Mytest.xs" printf("hello"); #line 25 "Mytest.c" } XSRETURN_EMPTY; }
Az XS-ből generált C fájl 3/3 #ifdef __cplusplus extern "C" #endif XS(boot_Mytest) { dXSARGS; char* file = __FILE__; XS_VERSION_BOOTCHECK ; newXS("Mytest::hello", XS_Mytest_hello, file); XSRETURN_YES; }
Mytest.pm package Mytest; use 5.006; use strict; use warnings; require Exporter; require DynaLoader; our @ISA = qw(Exporter DynaLoader); our %EXPORT_TAGS = ( 'all' => [ qw() ] ); our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); our @EXPORT = qw(); our $VERSION = '0.01'; bootstrap Mytest $VERSION; 1; __END__
PHP kiterjesztés minta 1/3 /* include standard header */ #include "php.h" /* declaration of functions to be exported */ ZEND_FUNCTION(first_module); /* compiled function list so Zend knows what's in this module */ zend_function_entry firstmod_functions[] = { ZEND_FE(first_module, NULL) {NULL, NULL, NULL} };
PHP kiterjesztés minta 2/3 /* compiled module information */ zend_module_entry firstmod_module_entry = { STANDARD_MODULE_HEADER, "First Module", firstmod_functions, NULL, NULL, NULL, NULL, NULL, NO_VERSION_YET, STANDARD_MODULE_PROPERTIES };
PHP kiterjesztés minta 3/3 /* implement standard "stub" routine to introduce ourselves to Zend */ #if COMPILE_DL_FIRST_MODULE ZEND_GET_MODULE(firstmod) #endif /* implement function that is meant to be made available to PHP */ ZEND_FUNCTION(first_module) { long parameter; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", ¶meter) == FAILURE) { return; } RETURN_LONG(parameter); }
PHP kód amit ezt használja <?php dl("first_module.so"); $param = 2; $return = first_module($param); print("We sent '$param' and got '$return'"); ?>
PHP függvény prototípus ZEND_FUNCTION ( my_function ); Kifejtve: void zif_my_function( int ht,argumentumok száma zval * return_value, zval * this_ptr,objektum pointer int return_value_used,a hívónak kell a visszatérési érték? zend_executor_globals * executor_globals );
PHP kiterjesztés http://www.zend.com/apidoc/zend.php • Multi-process, single-thread • emalloc a memóriavesztés ellen, de nem többszálú • Van processz és szál startup/shutdown, de ezek a szálak nem konkurrensek
Java DLL dekorált név multi-thread PHP static/DLL nem dekorált név single-thread Összehasonlítás Perl • DLL/static • dekorált név • multi-thread? ScriptBasic • DLL/static • nem dekorált név • multi-thread