内容简介:To use sci as a shared libary from e.g. C++, follow along with this tutorial. We illustrate what is happening when you run the scriptInThis file is compiled into a Java class with one static method,
Libsci
To use sci as a shared libary from e.g. C++, follow along with this tutorial. We illustrate what is happening when you run the script libsci/compile
.
In libsci/src
we have the following Clojure file:
(ns sci.impl.libsci (:require [cheshire.core :as cheshire] [sci.core :as sci]) (:gen-class :methods [^{:static true} [evalString [String] String]])) (defn -evalString [s] (sci/binding [sci/out *out*] ;; this enables println etc. (str (sci/eval-string s ;; this brings cheshire.core into sci {:namespaces {'cheshire.core {'generate-string cheshire/generate-string}}}))))
This file is compiled into a Java class with one static method, evalString
. This will be our API for the native library. To make this library
more interesting, we enable println
by providing a value for *out*
in the
interpreter. Also we make the cheshire
library available, just to show that you can bring in your own Clojure
functions.
Now let's have a look at the bridging class between Java and C++:
package sci.impl; import org.graalvm.nativeimage.c.function.CEntryPoint; import org.graalvm.nativeimage.c.type.CCharPointer; import org.graalvm.nativeimage.c.type.CTypeConversion; import com.oracle.svm.core.c.CConst; public final class LibSci { @CEntryPoint(name = "eval_string") public static @CConst CCharPointer evalString(@CEntryPoint.IsolateThreadContext long isolateId, @CConst CCharPointer s) { String expr = CTypeConversion.toJavaString(s); String result = sci.impl.libsci.evalString(expr); CTypeConversion.CCharPointerHolder holder = CTypeConversion.toCString(result); CCharPointer value = holder.get(); return value; } }
Here we wrap the static method evalString
into a native library function that
is given the name eval_string
. We use GraalVM's API to convert between Java
and C types.
The Clojure and Java code is compiled into .class files. Next, we compile those
.class files into a shared library using native-image
:
$ $GRAALVM_HOME/bin/native-image \ -jar $SCI_JAR \ -cp libsci/src \ -H:Name=libsci \ --shared \ ...
This begets the files graal_isolate_dynamic.h
, graal_isolate.h
, libsci.h
, libsci.dylib
(on linux libsci.so
) and libsci_dynamic.h
. We move all these files to libsci/target
.
Let's use the library from a C++ program now. Here's the code:
#include <iostream> #include <libsci.h> int main(int argc, char* argv[]) { graal_isolate_t *isolate = NULL; graal_isolatethread_t *thread = NULL; if (graal_create_isolate(NULL, &isolate, &thread) != 0) { fprintf(stderr, "initialization error\n"); return 1; } char *result = eval_string((long)thread, &argv[1][0]); std::cout << result << std::endl; return 0; }
This code gets the first command line argument and feeds it into libsci
's
function eval_string
. We compile this code as follows:
$ g++ libsci/src/from_cpp.cpp -L libsci/target -I libsci/target -lsci -o libsci/target/from_cpp
To run, we first have to set an environment variable to locate the shared libary:
$ export DYLD_LIBRARY_PATH=libsci/target
On linux this environment variable is called LD_LIBRARY_PATH
.
Now, let's run it.
$ time libsci/target/from_cpp " (println :foo) (require '[cheshire.core :as cheshire]) (cheshire/generate-string {:a 1})" :foo {"a":1} libsci/target/from_cpp 0.01s user 0.01s system 64% cpu 0.026 total
It worked. First we printed a keyword from within the interpreter. Then we returned a Clojure hash-map that was converted into JSON by cheshire. And then we printed the JSON string from the C++ program.
References
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
疯狂Java讲义
李刚 / 电子工业出版社 / 2008-10 / 99.00元
《疯狂Java讲义》2000年至今,Java语言一直是应用最广的开发语言,并拥有最广泛的开发人群。如今,Java已经不再简单地是一门语言,它更像一个完整的体系,一个系统的开发平台。更甚至,它被延伸成一种开源精神。 《疯狂Java讲义》深入介绍了Java编程的相关方面,全书内容覆盖了Java的基本语法结构、Java的面向对象特征、Java集合框架体系、Java泛型、异常处理、Java GUI编......一起来看看 《疯狂Java讲义》 这本书的介绍吧!