├── .idea ├── .name ├── copyright │ └── profiles_settings.xml ├── scopes │ └── scope_settings.xml ├── vcs.xml ├── encodings.xml ├── libraries │ ├── KotlinJavaRuntime.xml │ └── com_github_jnr_jnr_ffi_1_0_10.xml ├── kotlin-ffi-samples.iml ├── compiler.xml ├── modules.xml ├── misc.xml └── uiDesigner.xml ├── native ├── .gitignore ├── bench │ ├── CMakeLists.txt │ ├── bench_functions.h │ ├── bench_functions.cpp │ ├── bench_functions_jni.h │ └── bench_functions_jni.cpp ├── CMakeLists.txt └── bench_swig │ ├── SWIGTYPE_p_f_int__int.java │ ├── CMakeLists.txt │ ├── benchFunctions.java │ ├── benchFunctionsJNI.java │ ├── kffis_struct1.java │ └── bench_functions_swig.cpp ├── ffi-bench └── src │ ├── main.kt │ ├── measurements.kt │ ├── jnibench.kt │ ├── jnrbench.kt │ ├── jnrcallback.kt │ ├── bridjbench.kt │ └── swigbench.kt ├── jnr-getpid ├── src │ └── pidtest.kt └── jnr-getpid.iml ├── hello-armadillo ├── hello-armadillo.iml └── src │ └── armatest.kt ├── jnr-gettimeofday ├── jnr-gettimeofday.iml └── src │ └── Gettimeofday.kt ├── kotlin-ffi-samples.iml ├── README.md └── .gitignore /.idea/.name: -------------------------------------------------------------------------------- 1 | kjnr-samples -------------------------------------------------------------------------------- /native/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | lib -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /native/bench/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | set(LIB_SOURCE_FILES bench_functions.cpp bench_functions_jni.cpp) 3 | add_library(kotlinffibench SHARED ${LIB_SOURCE_FILES}) 4 | 5 | -------------------------------------------------------------------------------- /.idea/scopes/scope_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /ffi-bench/src/main.kt: -------------------------------------------------------------------------------- 1 | 2 | package ffibench 3 | 4 | fun main(args: Array) { 5 | val repeats = 10000 6 | jnrcb.measureAll(repeats) 7 | jnr.measureAll(repeats) 8 | jni.measureAll(repeats) 9 | bridj.measureAll(repeats) 10 | // swig.measureAll(repeats) 11 | } -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/libraries/KotlinJavaRuntime.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /jnr-getpid/src/pidtest.kt: -------------------------------------------------------------------------------- 1 | 2 | package getpid 3 | 4 | import jnr.ffi.* 5 | import jnr.ffi.types.pid_t 6 | 7 | 8 | public trait LibC { 9 | pid_t fun getpid() : Long 10 | pid_t fun getppid() : Long 11 | } 12 | 13 | fun main(args: Array) { 14 | val libc = LibraryLoader.create(javaClass()).load("c") 15 | 16 | println("pid=${libc.getpid()} parent pid=${libc.getppid()}") 17 | } 18 | 19 | -------------------------------------------------------------------------------- /native/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.4) 2 | project(kotlin_ffi_samples_native) 3 | 4 | find_package(Java REQUIRED COMPONENTS Runtime Development) 5 | find_package(JNI REQUIRED) 6 | 7 | include(UseJava) 8 | 9 | message (STATUS "JNI_INCLUDE_DIRS=${JNI_INCLUDE_DIRS}") 10 | message (STATUS "JNI_LIBRARIES=${JNI_LIBRARIES}") 11 | 12 | include_directories(".") 13 | include_directories(${JNI_INCLUDE_DIRS}) 14 | 15 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/lib") 16 | 17 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") 18 | 19 | add_subdirectory("bench") 20 | add_subdirectory("bench_swig") 21 | 22 | -------------------------------------------------------------------------------- /jnr-getpid/jnr-getpid.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /hello-armadillo/hello-armadillo.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /jnr-gettimeofday/jnr-gettimeofday.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /kotlin-ffi-samples.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /.idea/kotlin-ffi-samples.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | -------------------------------------------------------------------------------- /native/bench/bench_functions.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _KOTLIN_FFI_SAMPLES_BENCH_FUNCTIONS_H_ 3 | #define _KOTLIN_FFI_SAMPLES_BENCH_FUNCTIONS_H_ 4 | 5 | #ifdef SWIG 6 | %module example 7 | %{ 8 | #include "header.h" 9 | %} 10 | #endif 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif 15 | 16 | int kffis_func_int_int(int param); 17 | 18 | int kffis_func_string_int(const char* param); 19 | 20 | char* kffis_func_int_string(int param); 21 | 22 | struct kffis_struct1 { 23 | int int_field; 24 | const char* string_field; 25 | }; 26 | 27 | int kffis_func_struct1_int(kffis_struct1* param); 28 | 29 | kffis_struct1* kffis_func_int_struct1(int param); 30 | 31 | int kffis_func_callback_int(int (*cb)(int)); 32 | 33 | #ifdef __cplusplus 34 | } 35 | #endif 36 | 37 | #endif // _KOTLIN_FFI_SAMPLES_BENCH_FUNCTIONS_H_ -------------------------------------------------------------------------------- /native/bench/bench_functions.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "bench_functions.h" 3 | #include 4 | 5 | int kffis_func_int_int(int param) 6 | { 7 | return param % 42 + 1; 8 | } 9 | 10 | int kffis_func_string_int(const char* param) 11 | { 12 | return strlen(param); 13 | } 14 | 15 | char string_back[] = "greetings from native"; 16 | 17 | char* kffis_func_int_string(int param) 18 | { 19 | return string_back; 20 | } 21 | 22 | int kffis_func_struct1_int(kffis_struct1* param) 23 | { 24 | return param->int_field % 42 + strlen(param->string_field); 25 | } 26 | 27 | kffis_struct1 struct_back = { 42, string_back }; 28 | 29 | kffis_struct1* kffis_func_int_struct1(int param) 30 | { 31 | return &struct_back; 32 | } 33 | 34 | int kffis_func_callback_int(int (*cb)(int)) 35 | { 36 | return cb ? cb(42) : -1; 37 | } 38 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /hello-armadillo/src/armatest.kt: -------------------------------------------------------------------------------- 1 | 2 | package armatest 3 | 4 | import jnr.ffi.* 5 | import jnr.ffi.Pointer 6 | 7 | public trait LibArma4ffi { 8 | fun release_mat(mat: Pointer): Unit 9 | fun randu_mat(rows: Int, cols: Int): Pointer 10 | fun mul_mat(a: Pointer, b: Pointer): Pointer 11 | fun t_mat(mat: Pointer): Pointer 12 | fun print_mat(mat: Pointer): Unit 13 | } 14 | 15 | fun main(args: Array) { 16 | val libkarma = LibraryLoader.create(javaClass()).load("arma4ffi") 17 | 18 | println("start") 19 | 20 | val A = libkarma.randu_mat(4,5) 21 | val B = libkarma.randu_mat(4,5) 22 | val Bt = libkarma.t_mat(B) 23 | libkarma.release_mat(B) 24 | val ABt = libkarma.mul_mat(A, Bt) 25 | libkarma.release_mat(A) 26 | libkarma.print_mat(ABt) 27 | libkarma.release_mat(ABt) 28 | 29 | println("done") 30 | } 31 | -------------------------------------------------------------------------------- /native/bench_swig/SWIGTYPE_p_f_int__int.java: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | * This file was automatically generated by SWIG (http://www.swig.org). 3 | * Version 3.0.2 4 | * 5 | * Do not make changes to this file unless you know what you are doing--modify 6 | * the SWIG interface file instead. 7 | * ----------------------------------------------------------------------------- */ 8 | 9 | package ffibench.swig; 10 | 11 | public class SWIGTYPE_p_f_int__int { 12 | private long swigCPtr; 13 | 14 | protected SWIGTYPE_p_f_int__int(long cPtr, boolean futureUse) { 15 | swigCPtr = cPtr; 16 | } 17 | 18 | protected SWIGTYPE_p_f_int__int() { 19 | swigCPtr = 0; 20 | } 21 | 22 | protected static long getCPtr(SWIGTYPE_p_f_int__int obj) { 23 | return (obj == null) ? 0 : obj.swigCPtr; 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /native/bench_swig/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | find_package(Java REQUIRED COMPONENTS Runtime Development) 3 | find_package(JNI REQUIRED) 4 | find_package(SWIG REQUIRED) 5 | include(UseJava) 6 | include(UseSWIG) 7 | 8 | message (STATUS "JNI_INCLUDE_DIRS=${JNI_INCLUDE_DIRS}") 9 | message (STATUS "JNI_LIBRARIES=${JNI_LIBRARIES}") 10 | 11 | include_directories(${JNI_INCLUDE_DIRS}) 12 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}) 13 | 14 | set(CMAKE_SWIG_FLAGS -package bench_functions) 15 | # set(CMAKE_SWIG_OUTDIR "${PROJECT_SOURCE_DIR}swig/") 16 | set(CMAKE_SWIG_OUTDIR "swig") 17 | 18 | set_source_files_properties(../bench/bench_functions.h PROPERTIES CPLUSPLUS ON) 19 | set_source_files_properties(../bench/bench_functions.h PROPERTIES SWIG_FLAGS "-includeall") 20 | 21 | swig_add_module(bench_functions_swig java ../bench/bench_functions.h ../bench/bench_functions.cpp bench_functions_swig.cpp) 22 | swig_link_libraries(bench_functions_swig ${JNI_LIBRARIES}) 23 | -------------------------------------------------------------------------------- /native/bench/bench_functions_jni.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _KOTLIN_FFI_SAMPLES_BENCH_FUNCTIONS_JNI_H_ 3 | #define _KOTLIN_FFI_SAMPLES_BENCH_FUNCTIONS_JNI_H_ 4 | 5 | #include 6 | 7 | extern "C" { 8 | 9 | JNIEXPORT jint JNICALL Java_ffibench_jni_LibFfiBench_funcIntInt(JNIEnv * env, jobject obj, jint param); 10 | 11 | JNIEXPORT jint JNICALL Java_ffibench_jni_LibFfiBench_funcStringInt(JNIEnv * env, jobject obj, jstring param); 12 | 13 | JNIEXPORT jstring JNICALL Java_ffibench_jni_LibFfiBench_funcIntString(JNIEnv * env, jobject obj, jint param); 14 | 15 | JNIEXPORT jint JNICALL Java_ffibench_jni_LibFfiBench_funcStruct1Int(JNIEnv * env, jobject obj, jobject param); 16 | 17 | JNIEXPORT jobject JNICALL Java_ffibench_jni_LibFfiBench_funcIntStruct1(JNIEnv * env, jobject obj, jint param); 18 | 19 | JNIEXPORT jint JNICALL Java_ffibench_jni_LibFfiBench_funcCallbackInt(JNIEnv * env, jobject obj, jobject param); 20 | 21 | } 22 | 23 | #endif // _KOTLIN_FFI_SAMPLES_BENCH_FUNCTIONS_JNI_H_ 24 | -------------------------------------------------------------------------------- /ffi-bench/src/measurements.kt: -------------------------------------------------------------------------------- 1 | 2 | package ffibench.measurements 3 | 4 | 5 | fun asserted_measure(f: () -> T, assert_f: (v: T) -> Unit, repeats: Int, calibration: Long = 0): Long { 6 | var r = repeats - 1; 7 | var res = f() 8 | assert_f( res) 9 | val start = System.nanoTime() 10 | while (r-- > 0) 11 | res = f() 12 | val time = (System.nanoTime() - start) / 1000 - calibration; 13 | assert_f( res) 14 | return time 15 | } 16 | 17 | fun assert_equals(v: T, expected: T) { 18 | assert(v == expected, "assertion failed: expected '$expected' but got '$v'") 19 | } 20 | 21 | fun unasserted_measure(f: () -> T, repeats: Int, calibration: Long = 0): Long 22 | = asserted_measure( f, { (_) -> ; }, repeats, calibration) 23 | 24 | fun assert_equals_measure(f: () -> T, expected: T, repeats: Int, calibration: Long = 0): Long 25 | = asserted_measure( f, { (v) -> assert_equals(v, expected) }, repeats, calibration) 26 | 27 | fun dummy() {} 28 | 29 | -------------------------------------------------------------------------------- /jnr-gettimeofday/src/Gettimeofday.kt: -------------------------------------------------------------------------------- 1 | package gettimeofday 2 | 3 | import jnr.ffi.* 4 | import jnr.ffi.types.* 5 | import jnr.ffi.annotations.Out 6 | import jnr.ffi.annotations.Transient 7 | import jnr.ffi.Struct.SignedLong 8 | import jnr.ffi.Struct.time_t 9 | 10 | /** 11 | * Retrieves the current system time using gettimeofday(3) 12 | */ 13 | public class Gettimeofday { 14 | public class Timeval(runtime: Runtime) : Struct(runtime) { 15 | public val tv_sec: time_t = super.time_t() 16 | public val tv_usec: SignedLong = super.SignedLong() 17 | } 18 | 19 | public trait LibC { 20 | public fun gettimeofday(Out Transient tv: Timeval, unused: Pointer?): Int 21 | } 22 | 23 | class object { 24 | 25 | public fun main(args: Array) { 26 | val libc = LibraryLoader.create(javaClass()).load("c") 27 | val runtime = Runtime.getRuntime(libc) 28 | 29 | val tv = Timeval(runtime) 30 | libc.gettimeofday(tv, null) 31 | System.out.println("gettimeofday tv.tv_sec=" + tv.tv_sec.get() + " tv.tv_usec=" + tv.tv_usec.get()) 32 | } 33 | } 34 | } 35 | 36 | fun main(args: Array) = Gettimeofday.main(args) 37 | -------------------------------------------------------------------------------- /.idea/libraries/com_github_jnr_jnr_ffi_1_0_10.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /native/bench_swig/benchFunctions.java: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | * This file was automatically generated by SWIG (http://www.swig.org). 3 | * Version 3.0.2 4 | * 5 | * Do not make changes to this file unless you know what you are doing--modify 6 | * the SWIG interface file instead. 7 | * ----------------------------------------------------------------------------- */ 8 | 9 | package ffibench.swig; 10 | 11 | public class benchFunctions { 12 | public static int kffis_func_int_int(int param) { 13 | return benchFunctionsJNI.kffis_func_int_int(param); 14 | } 15 | 16 | public static int kffis_func_string_int(String param) { 17 | return benchFunctionsJNI.kffis_func_string_int(param); 18 | } 19 | 20 | public static String kffis_func_int_string(int param) { 21 | return benchFunctionsJNI.kffis_func_int_string(param); 22 | } 23 | 24 | public static int kffis_func_struct1_int(kffis_struct1 param) { 25 | return benchFunctionsJNI.kffis_func_struct1_int(kffis_struct1.getCPtr(param), param); 26 | } 27 | 28 | public static kffis_struct1 kffis_func_int_struct1(int param) { 29 | long cPtr = benchFunctionsJNI.kffis_func_int_struct1(param); 30 | return (cPtr == 0) ? null : new kffis_struct1(cPtr, false); 31 | } 32 | 33 | public static int kffis_func_callback_int(SWIGTYPE_p_f_int__int cb) { 34 | return benchFunctionsJNI.kffis_func_callback_int(SWIGTYPE_p_f_int__int.getCPtr(cb)); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 1.7 25 | 26 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /native/bench_swig/benchFunctionsJNI.java: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | * This file was automatically generated by SWIG (http://www.swig.org). 3 | * Version 3.0.2 4 | * 5 | * Do not make changes to this file unless you know what you are doing--modify 6 | * the SWIG interface file instead. 7 | * ----------------------------------------------------------------------------- */ 8 | 9 | package ffibench.swig; 10 | 11 | public class benchFunctionsJNI { 12 | public final static native int kffis_func_int_int(int jarg1); 13 | public final static native int kffis_func_string_int(String jarg1); 14 | public final static native String kffis_func_int_string(int jarg1); 15 | public final static native void kffis_struct1_int_field_set(long jarg1, kffis_struct1 jarg1_, int jarg2); 16 | public final static native int kffis_struct1_int_field_get(long jarg1, kffis_struct1 jarg1_); 17 | public final static native void kffis_struct1_string_field_set(long jarg1, kffis_struct1 jarg1_, String jarg2); 18 | public final static native String kffis_struct1_string_field_get(long jarg1, kffis_struct1 jarg1_); 19 | public final static native long new_kffis_struct1(); 20 | public final static native void delete_kffis_struct1(long jarg1); 21 | public final static native int kffis_func_struct1_int(long jarg1, kffis_struct1 jarg1_); 22 | public final static native long kffis_func_int_struct1(int jarg1); 23 | public final static native int kffis_func_callback_int(long jarg1); 24 | } 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Kotlin FFI samples 2 | ================== 3 | 4 | Contains samples of FFI usage from Kotlin: 5 | 6 | *Note*: require Kotlin M10 or later 7 | 8 | 1. _pidtest_ - direct port of JNR GetPid sample (https://github.com/jnr/jnr-ffi-examples/tree/master/getpid/src/main/java/getpid) 9 | 10 | 2. _armatest_ - example of using sample wrapper around Armadillo (http://arma.sourceforge.net/) lib via JNR, 11 | reproducing tutorial sample from the lib. (wrapper could be taken from https://github.com/ligee/armadillo-4ffi, compiled 12 | library should be placed into the folder where jnr-ffi loader may find it, e.g. in the project root) 13 | 14 | 3. _ffi-bench_ - benchmarking various FFI approaches: 15 | - JNI 16 | - JNR 17 | - BridJ - _works with some problems, namely value extraction from struct doesn't work_ 18 | 19 | ffi-bench results: 20 | ------------------ 21 | 22 | JNR results (10000 repeats, calibrated to 0us) 23 | 24 | int->int: 2732us 25 | string->int: 48087us 26 | int->string: 2288us 27 | int->struct1: 19321us 28 | struct1->int: 7321us 29 | callback->int: 11167us 30 | 31 | JNI results (10000 repeats, calibrated to 0us) 32 | 33 | int->int: 2009us 34 | string->int: 6210us 35 | int->string: 2756us 36 | int->struct1: 17029us 37 | struct1->int: 8899us 38 | callback->int: 7004us 39 | 40 | BridJ results (10000 repeats, calibrated to 0us) 41 | 42 | int->int: 2158us 43 | string->int: 50564us 44 | int->string: 2098us 45 | int->struct1: 11100us 46 | struct1->int: 5650us 47 | callback->int: 10994us 48 | -------------------------------------------------------------------------------- /native/bench_swig/kffis_struct1.java: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | * This file was automatically generated by SWIG (http://www.swig.org). 3 | * Version 3.0.2 4 | * 5 | * Do not make changes to this file unless you know what you are doing--modify 6 | * the SWIG interface file instead. 7 | * ----------------------------------------------------------------------------- */ 8 | 9 | package ffibench.swig; 10 | 11 | public class kffis_struct1 { 12 | private long swigCPtr; 13 | protected boolean swigCMemOwn; 14 | 15 | protected kffis_struct1(long cPtr, boolean cMemoryOwn) { 16 | swigCMemOwn = cMemoryOwn; 17 | swigCPtr = cPtr; 18 | } 19 | 20 | protected static long getCPtr(kffis_struct1 obj) { 21 | return (obj == null) ? 0 : obj.swigCPtr; 22 | } 23 | 24 | protected void finalize() { 25 | delete(); 26 | } 27 | 28 | public synchronized void delete() { 29 | if (swigCPtr != 0) { 30 | if (swigCMemOwn) { 31 | swigCMemOwn = false; 32 | benchFunctionsJNI.delete_kffis_struct1(swigCPtr); 33 | } 34 | swigCPtr = 0; 35 | } 36 | } 37 | 38 | public void setInt_field(int value) { 39 | benchFunctionsJNI.kffis_struct1_int_field_set(swigCPtr, this, value); 40 | } 41 | 42 | public int getInt_field() { 43 | return benchFunctionsJNI.kffis_struct1_int_field_get(swigCPtr, this); 44 | } 45 | 46 | public void setString_field(String value) { 47 | benchFunctionsJNI.kffis_struct1_string_field_set(swigCPtr, this, value); 48 | } 49 | 50 | public String getString_field() { 51 | return benchFunctionsJNI.kffis_struct1_string_field_get(swigCPtr, this); 52 | } 53 | 54 | public kffis_struct1() { 55 | this(benchFunctionsJNI.new_kffis_struct1(), true); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /ffi-bench/src/jnibench.kt: -------------------------------------------------------------------------------- 1 | 2 | package ffibench.jni 3 | 4 | import ffibench.measurements.* 5 | 6 | public class LibFfiBench { 7 | { 8 | System.loadLibrary("kotlinffibench") 9 | } 10 | 11 | native fun funcIntInt(param: Int): Int 12 | native fun funcStringInt(param: String): Int 13 | native fun funcIntString(param: Int): String 14 | native fun funcStruct1Int(param: struct1): Int 15 | native fun funcIntStruct1(param: Int): struct1 16 | native fun funcCallbackInt(cb: callback1): Int 17 | } 18 | 19 | class struct1(i: Int = 0, s: String = String()) { 20 | public var int_field: Int = i 21 | public var string_field: String = s 22 | } 23 | 24 | public class callback1 { 25 | public fun callback(param: Int): Int { 26 | return param % 42 + 1; 27 | } 28 | } 29 | 30 | fun measureAll(repeats: Int) { 31 | val libffi = LibFfiBench() 32 | val calibration: Long = 0 //unasserted_measure({ dummy() }, repeats) 33 | 34 | println("JNI results ($repeats repeats, calibrated to ${calibration}us)") 35 | 36 | println("int->int: ${assert_equals_measure({ libffi.funcIntInt(33) }, 34, repeats, calibration)}us") 37 | 38 | println("string->int: ${assert_equals_measure({ libffi.funcStringInt("from kotlin") }, 11, repeats, calibration)}us") 39 | 40 | println("int->string: ${assert_equals_measure({ libffi.funcIntString(1) }, "greetings from native", repeats, calibration)}us") 41 | 42 | var st1 = libffi.funcIntStruct1(22) 43 | assert_equals( st1.int_field, 42) 44 | assert_equals( st1.string_field , "greetings from native") 45 | println("int->struct1: ${unasserted_measure({ libffi.funcIntStruct1(22) }, repeats, calibration)}us") 46 | 47 | st1.int_field = 10 48 | st1.string_field = "hi back" 49 | assert_equals( libffi.funcStruct1Int(st1), 10 + 7) 50 | println("struct1->int: ${unasserted_measure({ libffi.funcStruct1Int(st1) }, repeats, calibration)}us") 51 | 52 | val callback = callback1() 53 | println("callback->int: ${assert_equals_measure({ libffi.funcCallbackInt(callback) }, 1, repeats, calibration)}us") 54 | } 55 | -------------------------------------------------------------------------------- /native/bench/bench_functions_jni.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "bench_functions_jni.h" 3 | #include "bench_functions.h" 4 | 5 | jint Java_ffibench_jni_LibFfiBench_funcIntInt(JNIEnv * env, jobject obj, jint param) 6 | { 7 | return (jint)kffis_func_int_int((int)param); 8 | } 9 | 10 | jint JNICALL Java_ffibench_jni_LibFfiBench_funcStringInt(JNIEnv * env, jobject obj, jstring param) 11 | { 12 | const char *str = env->GetStringUTFChars(param, NULL); 13 | auto res = (jint)kffis_func_string_int(str ? str : ""); 14 | env->ReleaseStringUTFChars(param, str); 15 | return res; 16 | } 17 | 18 | jstring Java_ffibench_jni_LibFfiBench_funcIntString(JNIEnv * env, jobject obj, jint param) 19 | { 20 | return env->NewStringUTF(kffis_func_int_string(param)); 21 | } 22 | 23 | jint Java_ffibench_jni_LibFfiBench_funcStruct1Int(JNIEnv * env, jobject, jobject param) 24 | { 25 | jclass cls = env->GetObjectClass(param); 26 | jfieldID int_fid = env->GetFieldID(cls, "int_field", "I"); 27 | jfieldID str_fid = env->GetFieldID(cls, "string_field", "Ljava/lang/String;"); 28 | kffis_struct1 str1; 29 | str1.int_field = env->GetIntField(param, int_fid); 30 | jstring str_fld = (jstring)env->GetObjectField(param, str_fid); 31 | str1.string_field = env->GetStringUTFChars(str_fld, NULL); 32 | auto res = (jint)kffis_func_struct1_int(&str1); 33 | env->ReleaseStringUTFChars(str_fld, str1.string_field); 34 | return res; 35 | } 36 | 37 | jobject Java_ffibench_jni_LibFfiBench_funcIntStruct1(JNIEnv * env, jobject, jint param) 38 | { 39 | auto str1 = kffis_func_int_struct1((int)param); 40 | jclass cls = env->FindClass("ffibench/jni/struct1"); 41 | jfieldID int_fid = env->GetFieldID(cls, "int_field", "I"); 42 | jfieldID str_fid = env->GetFieldID(cls, "string_field", "Ljava/lang/String;"); 43 | jobject obj = env->AllocObject(cls); 44 | env->SetIntField(obj, int_fid, str1->int_field); 45 | jstring s_val = (jstring) env->NewStringUTF(str1->string_field); 46 | env->SetObjectField(obj, str_fid, s_val); 47 | return obj; 48 | } 49 | 50 | jint Java_ffibench_jni_LibFfiBench_funcCallbackInt(JNIEnv * env, jobject obj, jobject param) 51 | { 52 | jclass cls = env->GetObjectClass(param); 53 | jmethodID cb_mid = env->GetMethodID(cls, "callback", "(I)I"); 54 | return env->CallIntMethod(param, cb_mid, 42); 55 | } 56 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .gitignore support plugin (hsz.mobi) 2 | ### JetBrains template 3 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm 4 | 5 | #*.iml 6 | 7 | ## Directory-based project format: 8 | #.idea/ 9 | #*/.idea 10 | # if you remove the above rule, at least ignore the following: 11 | 12 | # User-specific stuff: 13 | .idea/workspace.xml 14 | .idea/tasks.xml 15 | .idea/dictionaries 16 | 17 | # Sensitive or high-churn files: 18 | .idea/dataSources.ids 19 | .idea/dataSources.xml 20 | .idea/sqlDataSources.xml 21 | .idea/dynamic.xml 22 | .idea/uiDesigner.xml 23 | 24 | # Gradle: 25 | .idea/gradle.xml 26 | .idea/libraries 27 | 28 | # Mongo Explorer plugin: 29 | .idea/mongoSettings.xml 30 | 31 | ## File-based project format: 32 | *.ipr 33 | *.iws 34 | 35 | ## Plugin-specific files: 36 | 37 | # IntelliJ 38 | out/ 39 | 40 | # mpeltonen/sbt-idea plugin 41 | .idea_modules/ 42 | 43 | # JIRA plugin 44 | atlassian-ide-plugin.xml 45 | 46 | # Crashlytics plugin (for Android Studio and IntelliJ) 47 | com_crashlytics_export_strings.xml 48 | crashlytics.properties 49 | crashlytics-build.properties 50 | 51 | 52 | ### Java template 53 | *.class 54 | 55 | # Mobile Tools for Java (J2ME) 56 | .mtj.tmp/ 57 | 58 | # Package Files # 59 | *.jar 60 | *.war 61 | *.ear 62 | 63 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 64 | hs_err_pid* 65 | 66 | 67 | ### OSX template 68 | .DS_Store 69 | .AppleDouble 70 | .LSOverride 71 | 72 | # Icon must end with two \r 73 | Icon 74 | 75 | # Thumbnails 76 | ._* 77 | 78 | # Files that might appear on external disk 79 | .Spotlight-V100 80 | .Trashes 81 | 82 | # Directories potentially created on remote AFP share 83 | .AppleDB 84 | .AppleDesktop 85 | Network Trash Folder 86 | Temporary Items 87 | .apdisk 88 | 89 | 90 | 91 | ### CMake template 92 | CMakeCache.txt 93 | CMakeFiles 94 | Makefile 95 | cmake_install.cmake 96 | install_manifest.txt 97 | 98 | 99 | ### C template 100 | # Object files 101 | *.o 102 | *.ko 103 | *.obj 104 | *.elf 105 | 106 | # Precompiled Headers 107 | *.gch 108 | *.pch 109 | 110 | # Libraries 111 | *.lib 112 | *.a 113 | *.la 114 | *.lo 115 | 116 | # Shared objects (inc. Windows DLLs) 117 | *.dll 118 | *.so 119 | *.so.* 120 | *.dylib 121 | 122 | # Executables 123 | *.exe 124 | *.out 125 | *.app 126 | *.i*86 127 | *.x86_64 128 | *.hex 129 | 130 | -------------------------------------------------------------------------------- /ffi-bench/src/jnrbench.kt: -------------------------------------------------------------------------------- 1 | 2 | package ffibench.jnr 3 | 4 | import jnr.ffi.types.* 5 | import ffibench.measurements.* 6 | 7 | public trait LibFfiBench { 8 | fun kffis_func_int_int(param: Int): Int 9 | fun kffis_func_string_int(param: String): Int 10 | fun kffis_func_int_string(param: Int): String 11 | fun kffis_func_struct1_int(jnr.ffi.annotations.In param: struct1): Int 12 | fun kffis_func_int_struct1(param: Int): struct1 13 | fun kffis_func_callback_int(cb: Callback_int_int): Int 14 | } 15 | 16 | open class struct1(runtime: jnr.ffi.Runtime) : jnr.ffi.Struct(runtime) { 17 | public val int_field: jnr.ffi.Struct.Signed32 = super.Signed32() 18 | public open val string_field: jnr.ffi.Struct.AsciiStringRef = super.AsciiStringRef(256) 19 | } 20 | 21 | public trait Callback_int_int { 22 | jnr.ffi.annotations.Delegate 23 | public fun callback(param: Int): Int 24 | } 25 | 26 | public class callback1: Callback_int_int{ 27 | public override fun callback(param: Int): Int { 28 | return param % 42 + 1; 29 | } 30 | } 31 | 32 | fun measureAll(repeats: Int) { 33 | val libffi = jnr.ffi.LibraryLoader.create(javaClass()).load("kotlinffibench") 34 | 35 | val calibration: Long = 0 //unasserted_measure({ dummy() }, repeats) 36 | 37 | println("JNR results ($repeats repeats, calibrated to ${calibration}us)") 38 | 39 | println("int->int: ${assert_equals_measure({ libffi.kffis_func_int_int(33) }, 34, repeats, calibration)}us") 40 | 41 | val from_str = "from kotlin" 42 | println("string->int: ${assert_equals_measure({ libffi.kffis_func_string_int(from_str) }, 11, repeats, calibration)}us") 43 | 44 | println("int->string: ${assert_equals_measure({ libffi.kffis_func_int_string(1) }, "greetings from native", repeats, calibration)}us") 45 | 46 | var st1 = libffi.kffis_func_int_struct1(22) 47 | assert_equals( st1.int_field.get(), 42) 48 | assert_equals( st1.string_field.get() , "greetings from native") 49 | println("int->struct1: ${unasserted_measure({ libffi.kffis_func_int_struct1(22) }, repeats, calibration)}us") 50 | 51 | val runtime = jnr.ffi.Runtime.getRuntime(libffi) 52 | val st2 = struct1(runtime) 53 | st2.int_field.set(15) 54 | st2.string_field.set("hi back") 55 | assert_equals( libffi.kffis_func_struct1_int(st2), 22) 56 | println("struct1->int: ${unasserted_measure({ libffi.kffis_func_struct1_int(st2) }, repeats, calibration)}us") 57 | 58 | val callback = callback1() 59 | println("callback->int: ${assert_equals_measure({ libffi.kffis_func_callback_int(callback) }, 1, repeats, calibration)}us") 60 | 61 | println("struct2 size: ${jnr.ffi.Struct.size(st2)}") 62 | } -------------------------------------------------------------------------------- /ffi-bench/src/jnrcallback.kt: -------------------------------------------------------------------------------- 1 | 2 | package ffibench.jnrcb 3 | 4 | import jnr.ffi.types.* 5 | import ffibench.measurements.* 6 | import jnr.ffi.Pointer 7 | import jnr.ffi.mapper.ToNativeContext 8 | import jnr.ffi.mapper.FromNativeContext 9 | import jnr.ffi.mapper.FromNativeConverter 10 | import jnr.ffi.mapper.ToNativeConverter 11 | 12 | public class KTCallBack() { 13 | 14 | public trait Callback_int_int { 15 | jnr.ffi.annotations.Delegate 16 | public open fun callback(param: Int): Int 17 | } 18 | 19 | class object { 20 | 21 | // conversion doesn't work 22 | // \todo find out the reason and try the conversion variant 23 | ToNativeConverter.ToNative(nativeType = javaClass()) 24 | public fun toNative(fn: ((Int) -> Int)?, context: ToNativeContext): Callback_int_int? { 25 | return if (fn != null) object : Callback_int_int { override fun callback(param: Int): Int = fn(param) } else null 26 | } 27 | 28 | FromNativeConverter.FromNative(nativeType = javaClass()) 29 | public fun fromNative(value: Callback_int_int?, context: FromNativeContext): kotlin.Function1? { 30 | return null 31 | } 32 | } 33 | } 34 | 35 | public trait LibFfiBench { 36 | fun kffis_func_callback_int(cb: KTCallBack.Callback_int_int): Int 37 | } 38 | 39 | public class callback1: KTCallBack.Callback_int_int { 40 | override fun callback(param: Int): Int { 41 | return param % 42 + 1 42 | } 43 | } 44 | 45 | public class callback2(val fn: (Int) -> Int): KTCallBack.Callback_int_int { 46 | override fun callback(param: Int): Int = fn(param) 47 | } 48 | 49 | fun LibFfiBench.kffis_func_callback_int(cb: (Int) -> Int): Int = 50 | kffis_func_callback_int(callback2(cb)) 51 | // kffis_func_callback_int(object : KTCallBack.Callback_int_int() { override fun callback(param: Int): Int = cb(param) }) 52 | 53 | fun measureAll(repeats: Int) { 54 | val libffi = jnr.ffi.LibraryLoader.create(javaClass()).load("kotlinffibench") 55 | val calibration: Long = 0 //unasserted_measure({ dummy() }, repeats) 56 | 57 | println("JNR CB results ($repeats repeats, calibrated to ${calibration}us)") 58 | 59 | val callback_stat = callback1() 60 | val callback_dyn = { (a: Int) -> a % 42 + 1 } 61 | val callback_ds = callback2(callback_dyn) 62 | 63 | println("callback->int (static): ${assert_equals_measure({ libffi.kffis_func_callback_int(callback_stat) }, 1, repeats, calibration)}us") 64 | println("callback->int (lambda): ${assert_equals_measure({ libffi.kffis_func_callback_int(callback_ds) }, 1, repeats, calibration)}us") 65 | println("callback->int (dynamic): ${assert_equals_measure({ libffi.kffis_func_callback_int(callback_dyn) }, 1, repeats, calibration)}us") 66 | } 67 | -------------------------------------------------------------------------------- /ffi-bench/src/bridjbench.kt: -------------------------------------------------------------------------------- 1 | 2 | package ffibench.bridj 3 | 4 | import org.bridj.* 5 | import org.bridj.ann.* 6 | import org.bridj.Pointer.* 7 | import ffibench.measurements.* 8 | 9 | Library("kotlinffibench") 10 | public class LibFfiBench { 11 | public native fun kffis_func_int_int(param: Int): Int 12 | public native fun kffis_func_string_int(param: Pointer): Int 13 | public native fun kffis_func_int_string(param: Int): Pointer 14 | public native fun kffis_func_struct1_int(param: Pointer): Int 15 | public native fun kffis_func_int_struct1(param: Int): Pointer 16 | public native fun kffis_func_callback_int(cb: Pointer): Int 17 | 18 | public abstract class CallbackType : Callback() { 19 | public abstract fun apply(param: Int): Int 20 | } 21 | 22 | { 23 | BridJ.register() 24 | } 25 | } 26 | 27 | class struct1(pointer: Pointer? = null) : StructObject(pointer) { 28 | Field(0) public fun int_field(v: Int): struct1 { this.io.setIntField(this, 0, v); return this } 29 | Field(0) public fun int_field(): Int = this.io.getIntField(this, 0) 30 | Field(1) public fun string_field(s: String): struct1 { this.io.setPointerField(this, 1, pointerToCString(s)); return this } 31 | Field(1) public fun string_field(): Pointer = this.io.getPointerField(this, 1) 32 | } 33 | 34 | public class callback1() : LibFfiBench.CallbackType() { 35 | public override fun apply(param: Int): Int { 36 | return param % 42 + 1; 37 | } 38 | } 39 | 40 | fun measureAll(repeats: Int) { 41 | val libffi = LibFfiBench() 42 | 43 | val calibration: Long = 0 //unasserted_measure({ dummy() }, repeats) 44 | 45 | println("BridJ results ($repeats repeats, calibrated to ${calibration}us)") 46 | 47 | println("int->int: ${assert_equals_measure({ libffi.kffis_func_int_int(33) }, 34, repeats, calibration)}us") 48 | 49 | println("string->int: ${assert_equals_measure({ libffi.kffis_func_string_int(pointerToCString("from kotlin")) }, 11, repeats, calibration)}us") 50 | 51 | println("int->string: ${assert_equals_measure({ libffi.kffis_func_int_string(1).getCString() }, "greetings from native", repeats, calibration)}us") 52 | 53 | var st1 = libffi.kffis_func_int_struct1(22) 54 | // assert_equals( st1.get().int_field(), 42) 55 | // assert_equals( st1.get().string_field(), "greetings from native") 56 | println("int->struct1: ${unasserted_measure({ libffi.kffis_func_int_struct1(22) }, repeats, calibration)}us") 57 | 58 | // st1.get().int_field(10) 59 | // st1.get().string_field("hi back") 60 | // assert_equals( libffi.kffis_func_struct1_int(st1), 10 + 7) 61 | println("struct1->int: ${unasserted_measure({ libffi.kffis_func_struct1_int(st1) }, repeats, calibration)}us") 62 | 63 | val callback = callback1() 64 | println("callback->int: ${assert_equals_measure({ libffi.kffis_func_callback_int(Pointer.pointerTo(callback)) }, 1, repeats, calibration)}us") 65 | } -------------------------------------------------------------------------------- /ffi-bench/src/swigbench.kt: -------------------------------------------------------------------------------- 1 | 2 | package ffibench.swig 3 | 4 | import kotlin.platform.platformStatic 5 | import ffibench.measurements.* 6 | 7 | public class benchFunctionsJNI { 8 | class object { 9 | { 10 | System.loadLibrary("bench_functions_swig") 11 | } 12 | 13 | public native platformStatic fun kffis_func_int_int(jarg1: Int): Int 14 | public native platformStatic fun kffis_func_string_int(jarg1: String): Int 15 | public native platformStatic fun kffis_func_int_string(jarg1: Int): String 16 | public native platformStatic fun kffis_struct1_int_field_set(jarg1: Long, jarg1_: kffis_struct1, jarg2: Int): Unit 17 | public native platformStatic fun kffis_struct1_int_field_get(jarg1: Long, jarg1_: kffis_struct1): Int 18 | public native platformStatic fun kffis_struct1_string_field_set(jarg1: Long, jarg1_: kffis_struct1, jarg2: String): Unit 19 | public native platformStatic fun kffis_struct1_string_field_get(jarg1: Long, jarg1_: kffis_struct1): String 20 | public native platformStatic fun new_kffis_struct1(): Long 21 | public native platformStatic fun delete_kffis_struct1(jarg1: Long): Unit 22 | public native platformStatic fun kffis_func_struct1_int(jarg1: Long, jarg1_: kffis_struct1): Int 23 | public native platformStatic fun kffis_func_int_struct1(jarg1: Int): Long 24 | public native platformStatic fun kffis_func_callback_int(jarg1: Long): Int 25 | } 26 | } 27 | 28 | public class libffi { 29 | class object { 30 | public fun kffis_func_int_int(param: Int): Int { 31 | return benchFunctionsJNI.kffis_func_int_int(param) 32 | } 33 | 34 | public fun kffis_func_string_int(param: String): Int { 35 | return benchFunctionsJNI.kffis_func_string_int(param) 36 | } 37 | 38 | public fun kffis_func_int_string(param: Int): String { 39 | return benchFunctionsJNI.kffis_func_int_string(param) 40 | } 41 | 42 | public fun kffis_func_struct1_int(param: kffis_struct1): Int { 43 | return benchFunctionsJNI.kffis_func_struct1_int(kffis_struct1.getCPtr(param), param) 44 | } 45 | 46 | public fun kffis_func_int_struct1(param: Int): kffis_struct1? { 47 | val cPtr = benchFunctionsJNI.kffis_func_int_struct1(param) 48 | return if ((cPtr == 0L)) null else kffis_struct1(cPtr, false) 49 | } 50 | 51 | public fun kffis_func_callback_int(cb: SWIGTYPE_p_f_int__int): Int { 52 | return benchFunctionsJNI.kffis_func_callback_int(SWIGTYPE_p_f_int__int.getCPtr(cb)) 53 | } 54 | } 55 | 56 | } 57 | 58 | 59 | public fun kffis_struct1(): kffis_struct1 { 60 | return kffis_struct1(benchFunctionsJNI.new_kffis_struct1(), true) 61 | } 62 | 63 | public class kffis_struct1(private var swigCPtr: Long, protected var swigCMemOwn: Boolean) { 64 | 65 | protected fun finalize() { 66 | delete() 67 | } 68 | 69 | synchronized public fun delete() { 70 | if (swigCPtr != 0L) { 71 | if (swigCMemOwn) { 72 | swigCMemOwn = false 73 | benchFunctionsJNI.delete_kffis_struct1(swigCPtr) 74 | } 75 | swigCPtr = 0 76 | } 77 | } 78 | 79 | public var int_field: Int 80 | set(value: Int) { benchFunctionsJNI.kffis_struct1_int_field_set(swigCPtr, this, value) } 81 | get(): Int { return benchFunctionsJNI.kffis_struct1_int_field_get(swigCPtr, this) } 82 | 83 | public var string_field: String 84 | set(value: String) { benchFunctionsJNI.kffis_struct1_string_field_set(swigCPtr, this, value) } 85 | get(): String { return benchFunctionsJNI.kffis_struct1_string_field_get(swigCPtr, this) } 86 | 87 | class object { 88 | 89 | public fun getCPtr(obj: kffis_struct1?): Long { 90 | return if ((obj == null)) 0 else obj.swigCPtr 91 | } 92 | } 93 | 94 | } 95 | 96 | 97 | public class SWIGTYPE_p_f_int__int(cPtr: Long = 0, futureUse: Boolean = false) { 98 | private var swigCPtr: Long = cPtr 99 | 100 | class object { 101 | 102 | public fun getCPtr(obj: SWIGTYPE_p_f_int__int?): Long { 103 | return if ((obj == null)) 0 else obj.swigCPtr 104 | } 105 | } 106 | } 107 | 108 | 109 | fun measureAll(repeats: Int) { 110 | val calibration: Long = 0 //unasserted_measure({ dummy() }, repeats) 111 | 112 | println("SWIG results ($repeats repeats, calibrated to ${calibration}us)") 113 | 114 | println("int->int: ${assert_equals_measure({ libffi.kffis_func_int_int(33) }, 33, repeats, calibration)}us") 115 | 116 | val from_str = "from kotlin" 117 | println("string->int: ${assert_equals_measure({ libffi.kffis_func_string_int(from_str) }, 11, repeats, calibration)}us") 118 | 119 | println("int->string: ${assert_equals_measure({ libffi.kffis_func_int_int(1) }, "greetings from native", repeats, calibration)}us") 120 | 121 | var st1 = libffi.kffis_func_int_struct1(22) 122 | assert_equals( st1!!.int_field, 42) 123 | assert_equals( st1!!.string_field , "greetings from native") 124 | println("int->struct1: ${unasserted_measure({ libffi.kffis_func_int_struct1(22) }, repeats, calibration)}us") 125 | 126 | st1!!.int_field = 10 127 | st1!!.string_field = "hi back" 128 | assert_equals( libffi.kffis_func_struct1_int(st1!!), 10 + 7) 129 | println("struct1->int: ${unasserted_measure({ libffi.kffis_func_struct1_int(st1!!) }, repeats, calibration)}us") 130 | 131 | // val callback = callback1() 132 | // println("callback->int: ${assert_equals_measure({ libffi.kffis_func_callback_int(callback) }, 1, repeats, calibration)}us") 133 | 134 | } 135 | -------------------------------------------------------------------------------- /.idea/uiDesigner.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /native/bench_swig/bench_functions_swig.cpp: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | * This file was automatically generated by SWIG (http://www.swig.org). 3 | * Version 3.0.2 4 | * 5 | * This file is not intended to be easily readable and contains a number of 6 | * coding conventions designed to improve portability and efficiency. Do not make 7 | * changes to this file unless you know what you are doing--modify the SWIG 8 | * interface file instead. 9 | * ----------------------------------------------------------------------------- */ 10 | 11 | #define SWIGJAVA 12 | 13 | 14 | #ifdef __cplusplus 15 | /* SwigValueWrapper is described in swig.swg */ 16 | template class SwigValueWrapper { 17 | struct SwigMovePointer { 18 | T *ptr; 19 | SwigMovePointer(T *p) : ptr(p) { } 20 | ~SwigMovePointer() { delete ptr; } 21 | SwigMovePointer& operator=(SwigMovePointer& rhs) { T* oldptr = ptr; ptr = 0; delete oldptr; ptr = rhs.ptr; rhs.ptr = 0; return *this; } 22 | } pointer; 23 | SwigValueWrapper& operator=(const SwigValueWrapper& rhs); 24 | SwigValueWrapper(const SwigValueWrapper& rhs); 25 | public: 26 | SwigValueWrapper() : pointer(0) { } 27 | SwigValueWrapper& operator=(const T& t) { SwigMovePointer tmp(new T(t)); pointer = tmp; return *this; } 28 | operator T&() const { return *pointer.ptr; } 29 | T *operator&() { return pointer.ptr; } 30 | }; 31 | 32 | template T SwigValueInit() { 33 | return T(); 34 | } 35 | #endif 36 | 37 | /* ----------------------------------------------------------------------------- 38 | * This section contains generic SWIG labels for method/variable 39 | * declarations/attributes, and other compiler dependent labels. 40 | * ----------------------------------------------------------------------------- */ 41 | 42 | /* template workaround for compilers that cannot correctly implement the C++ standard */ 43 | #ifndef SWIGTEMPLATEDISAMBIGUATOR 44 | # if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560) 45 | # define SWIGTEMPLATEDISAMBIGUATOR template 46 | # elif defined(__HP_aCC) 47 | /* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */ 48 | /* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */ 49 | # define SWIGTEMPLATEDISAMBIGUATOR template 50 | # else 51 | # define SWIGTEMPLATEDISAMBIGUATOR 52 | # endif 53 | #endif 54 | 55 | /* inline attribute */ 56 | #ifndef SWIGINLINE 57 | # if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__)) 58 | # define SWIGINLINE inline 59 | # else 60 | # define SWIGINLINE 61 | # endif 62 | #endif 63 | 64 | /* attribute recognised by some compilers to avoid 'unused' warnings */ 65 | #ifndef SWIGUNUSED 66 | # if defined(__GNUC__) 67 | # if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) 68 | # define SWIGUNUSED __attribute__ ((__unused__)) 69 | # else 70 | # define SWIGUNUSED 71 | # endif 72 | # elif defined(__ICC) 73 | # define SWIGUNUSED __attribute__ ((__unused__)) 74 | # else 75 | # define SWIGUNUSED 76 | # endif 77 | #endif 78 | 79 | #ifndef SWIG_MSC_UNSUPPRESS_4505 80 | # if defined(_MSC_VER) 81 | # pragma warning(disable : 4505) /* unreferenced local function has been removed */ 82 | # endif 83 | #endif 84 | 85 | #ifndef SWIGUNUSEDPARM 86 | # ifdef __cplusplus 87 | # define SWIGUNUSEDPARM(p) 88 | # else 89 | # define SWIGUNUSEDPARM(p) p SWIGUNUSED 90 | # endif 91 | #endif 92 | 93 | /* internal SWIG method */ 94 | #ifndef SWIGINTERN 95 | # define SWIGINTERN static SWIGUNUSED 96 | #endif 97 | 98 | /* internal inline SWIG method */ 99 | #ifndef SWIGINTERNINLINE 100 | # define SWIGINTERNINLINE SWIGINTERN SWIGINLINE 101 | #endif 102 | 103 | /* exporting methods */ 104 | #if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) 105 | # ifndef GCC_HASCLASSVISIBILITY 106 | # define GCC_HASCLASSVISIBILITY 107 | # endif 108 | #endif 109 | 110 | #ifndef SWIGEXPORT 111 | # if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) 112 | # if defined(STATIC_LINKED) 113 | # define SWIGEXPORT 114 | # else 115 | # define SWIGEXPORT __declspec(dllexport) 116 | # endif 117 | # else 118 | # if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY) 119 | # define SWIGEXPORT __attribute__ ((visibility("default"))) 120 | # else 121 | # define SWIGEXPORT 122 | # endif 123 | # endif 124 | #endif 125 | 126 | /* calling conventions for Windows */ 127 | #ifndef SWIGSTDCALL 128 | # if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) 129 | # define SWIGSTDCALL __stdcall 130 | # else 131 | # define SWIGSTDCALL 132 | # endif 133 | #endif 134 | 135 | /* Deal with Microsoft's attempt at deprecating C standard runtime functions */ 136 | #if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) 137 | # define _CRT_SECURE_NO_DEPRECATE 138 | #endif 139 | 140 | /* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */ 141 | #if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE) 142 | # define _SCL_SECURE_NO_DEPRECATE 143 | #endif 144 | 145 | 146 | 147 | /* Fix for jlong on some versions of gcc on Windows */ 148 | #if defined(__GNUC__) && !defined(__INTEL_COMPILER) 149 | typedef long long __int64; 150 | #endif 151 | 152 | /* Fix for jlong on 64-bit x86 Solaris */ 153 | #if defined(__x86_64) 154 | # ifdef _LP64 155 | # undef _LP64 156 | # endif 157 | #endif 158 | 159 | #include 160 | #include 161 | #include 162 | 163 | 164 | /* Support for throwing Java exceptions */ 165 | typedef enum { 166 | SWIG_JavaOutOfMemoryError = 1, 167 | SWIG_JavaIOException, 168 | SWIG_JavaRuntimeException, 169 | SWIG_JavaIndexOutOfBoundsException, 170 | SWIG_JavaArithmeticException, 171 | SWIG_JavaIllegalArgumentException, 172 | SWIG_JavaNullPointerException, 173 | SWIG_JavaDirectorPureVirtual, 174 | SWIG_JavaUnknownError 175 | } SWIG_JavaExceptionCodes; 176 | 177 | typedef struct { 178 | SWIG_JavaExceptionCodes code; 179 | const char *java_exception; 180 | } SWIG_JavaExceptions_t; 181 | 182 | 183 | static void SWIGUNUSED SWIG_JavaThrowException(JNIEnv *jenv, SWIG_JavaExceptionCodes code, const char *msg) { 184 | jclass excep; 185 | static const SWIG_JavaExceptions_t java_exceptions[] = { 186 | { SWIG_JavaOutOfMemoryError, "java/lang/OutOfMemoryError" }, 187 | { SWIG_JavaIOException, "java/io/IOException" }, 188 | { SWIG_JavaRuntimeException, "java/lang/RuntimeException" }, 189 | { SWIG_JavaIndexOutOfBoundsException, "java/lang/IndexOutOfBoundsException" }, 190 | { SWIG_JavaArithmeticException, "java/lang/ArithmeticException" }, 191 | { SWIG_JavaIllegalArgumentException, "java/lang/IllegalArgumentException" }, 192 | { SWIG_JavaNullPointerException, "java/lang/NullPointerException" }, 193 | { SWIG_JavaDirectorPureVirtual, "java/lang/RuntimeException" }, 194 | { SWIG_JavaUnknownError, "java/lang/UnknownError" }, 195 | { (SWIG_JavaExceptionCodes)0, "java/lang/UnknownError" } 196 | }; 197 | const SWIG_JavaExceptions_t *except_ptr = java_exceptions; 198 | 199 | while (except_ptr->code != code && except_ptr->code) 200 | except_ptr++; 201 | 202 | jenv->ExceptionClear(); 203 | excep = jenv->FindClass(except_ptr->java_exception); 204 | if (excep) 205 | jenv->ThrowNew(excep, msg); 206 | } 207 | 208 | 209 | /* Contract support */ 210 | 211 | #define SWIG_contract_assert(nullreturn, expr, msg) if (!(expr)) {SWIG_JavaThrowException(jenv, SWIG_JavaIllegalArgumentException, msg); return nullreturn; } else 212 | 213 | 214 | #include "../bench/bench_functions.h" 215 | 216 | 217 | #ifdef __cplusplus 218 | extern "C" { 219 | #endif 220 | 221 | SWIGEXPORT jint JNICALL Java_ffibench_swig_benchFunctionsJNI_kffis_1func_1int_1int(JNIEnv *jenv, jclass jcls, jint jarg1) { 222 | jint jresult = 0 ; 223 | int arg1 ; 224 | int result; 225 | 226 | (void)jenv; 227 | (void)jcls; 228 | arg1 = (int)jarg1; 229 | result = (int)kffis_func_int_int(arg1); 230 | jresult = (jint)result; 231 | return jresult; 232 | } 233 | 234 | 235 | SWIGEXPORT jint JNICALL Java_ffibench_swig_benchFunctionsJNI_kffis_1func_1string_1int(JNIEnv *jenv, jclass jcls, jstring jarg1) { 236 | jint jresult = 0 ; 237 | char *arg1 = (char *) 0 ; 238 | int result; 239 | 240 | (void)jenv; 241 | (void)jcls; 242 | arg1 = 0; 243 | if (jarg1) { 244 | arg1 = (char *)jenv->GetStringUTFChars(jarg1, 0); 245 | if (!arg1) return 0; 246 | } 247 | result = (int)kffis_func_string_int((char const *)arg1); 248 | jresult = (jint)result; 249 | if (arg1) jenv->ReleaseStringUTFChars(jarg1, (const char *)arg1); 250 | return jresult; 251 | } 252 | 253 | 254 | SWIGEXPORT jstring JNICALL Java_ffibench_swig_benchFunctionsJNI_kffis_1func_1int_1string(JNIEnv *jenv, jclass jcls, jint jarg1) { 255 | jstring jresult = 0 ; 256 | int arg1 ; 257 | char *result = 0 ; 258 | 259 | (void)jenv; 260 | (void)jcls; 261 | arg1 = (int)jarg1; 262 | result = (char *)kffis_func_int_string(arg1); 263 | if (result) jresult = jenv->NewStringUTF((const char *)result); 264 | return jresult; 265 | } 266 | 267 | 268 | SWIGEXPORT void JNICALL Java_ffibench_swig_benchFunctionsJNI_kffis_1struct1_1int_1field_1set(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2) { 269 | kffis_struct1 *arg1 = (kffis_struct1 *) 0 ; 270 | int arg2 ; 271 | 272 | (void)jenv; 273 | (void)jcls; 274 | (void)jarg1_; 275 | arg1 = *(kffis_struct1 **)&jarg1; 276 | arg2 = (int)jarg2; 277 | if (arg1) (arg1)->int_field = arg2; 278 | } 279 | 280 | 281 | SWIGEXPORT jint JNICALL Java_ffibench_swig_benchFunctionsJNI_kffis_1struct1_1int_1field_1get(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { 282 | jint jresult = 0 ; 283 | kffis_struct1 *arg1 = (kffis_struct1 *) 0 ; 284 | int result; 285 | 286 | (void)jenv; 287 | (void)jcls; 288 | (void)jarg1_; 289 | arg1 = *(kffis_struct1 **)&jarg1; 290 | result = (int) ((arg1)->int_field); 291 | jresult = (jint)result; 292 | return jresult; 293 | } 294 | 295 | 296 | SWIGEXPORT void JNICALL Java_ffibench_swig_benchFunctionsJNI_kffis_1struct1_1string_1field_1set(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2) { 297 | kffis_struct1 *arg1 = (kffis_struct1 *) 0 ; 298 | char *arg2 = (char *) 0 ; 299 | 300 | (void)jenv; 301 | (void)jcls; 302 | (void)jarg1_; 303 | arg1 = *(kffis_struct1 **)&jarg1; 304 | arg2 = 0; 305 | if (jarg2) { 306 | arg2 = (char *)jenv->GetStringUTFChars(jarg2, 0); 307 | if (!arg2) return ; 308 | } 309 | { 310 | if (arg2) { 311 | arg1->string_field = (char const *) (new char[strlen((const char *)arg2)+1]); 312 | strcpy((char *)arg1->string_field, (const char *)arg2); 313 | } else { 314 | arg1->string_field = 0; 315 | } 316 | } 317 | if (arg2) jenv->ReleaseStringUTFChars(jarg2, (const char *)arg2); 318 | } 319 | 320 | 321 | SWIGEXPORT jstring JNICALL Java_ffibench_swig_benchFunctionsJNI_kffis_1struct1_1string_1field_1get(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { 322 | jstring jresult = 0 ; 323 | kffis_struct1 *arg1 = (kffis_struct1 *) 0 ; 324 | char *result = 0 ; 325 | 326 | (void)jenv; 327 | (void)jcls; 328 | (void)jarg1_; 329 | arg1 = *(kffis_struct1 **)&jarg1; 330 | result = (char *) ((arg1)->string_field); 331 | if (result) jresult = jenv->NewStringUTF((const char *)result); 332 | return jresult; 333 | } 334 | 335 | 336 | SWIGEXPORT jlong JNICALL Java_ffibench_swig_benchFunctionsJNI_new_1kffis_1struct1(JNIEnv *jenv, jclass jcls) { 337 | jlong jresult = 0 ; 338 | kffis_struct1 *result = 0 ; 339 | 340 | (void)jenv; 341 | (void)jcls; 342 | result = (kffis_struct1 *)new kffis_struct1(); 343 | *(kffis_struct1 **)&jresult = result; 344 | return jresult; 345 | } 346 | 347 | 348 | SWIGEXPORT void JNICALL Java_ffibench_swig_benchFunctionsJNI_delete_1kffis_1struct1(JNIEnv *jenv, jclass jcls, jlong jarg1) { 349 | kffis_struct1 *arg1 = (kffis_struct1 *) 0 ; 350 | 351 | (void)jenv; 352 | (void)jcls; 353 | arg1 = *(kffis_struct1 **)&jarg1; 354 | delete arg1; 355 | } 356 | 357 | 358 | SWIGEXPORT jint JNICALL Java_ffibench_swig_benchFunctionsJNI_kffis_1func_1struct1_1int(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { 359 | jint jresult = 0 ; 360 | kffis_struct1 *arg1 = (kffis_struct1 *) 0 ; 361 | int result; 362 | 363 | (void)jenv; 364 | (void)jcls; 365 | (void)jarg1_; 366 | arg1 = *(kffis_struct1 **)&jarg1; 367 | result = (int)kffis_func_struct1_int(arg1); 368 | jresult = (jint)result; 369 | return jresult; 370 | } 371 | 372 | 373 | SWIGEXPORT jlong JNICALL Java_ffibench_swig_benchFunctionsJNI_kffis_1func_1int_1struct1(JNIEnv *jenv, jclass jcls, jint jarg1) { 374 | jlong jresult = 0 ; 375 | int arg1 ; 376 | kffis_struct1 *result = 0 ; 377 | 378 | (void)jenv; 379 | (void)jcls; 380 | arg1 = (int)jarg1; 381 | result = (kffis_struct1 *)kffis_func_int_struct1(arg1); 382 | *(kffis_struct1 **)&jresult = result; 383 | return jresult; 384 | } 385 | 386 | 387 | SWIGEXPORT jint JNICALL Java_ffibench_swig_benchFunctionsJNI_kffis_1func_1callback_1int(JNIEnv *jenv, jclass jcls, jlong jarg1) { 388 | jint jresult = 0 ; 389 | int (*arg1)(int) = (int (*)(int)) 0 ; 390 | int result; 391 | 392 | (void)jenv; 393 | (void)jcls; 394 | arg1 = *(int (**)(int))&jarg1; 395 | result = (int)kffis_func_callback_int(arg1); 396 | jresult = (jint)result; 397 | return jresult; 398 | } 399 | 400 | 401 | #ifdef __cplusplus 402 | } 403 | #endif 404 | 405 | --------------------------------------------------------------------------------