compiling a Clojure library to a shared native library (.so, .dylib) with Graalvm native-image

栏目: IT技术 · 发布时间: 4年前

内容简介: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


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

iOS Web应用开发

iOS Web应用开发

皮基 (Andrea Picchi) / 罗晴明 / 人民邮电出版社 / 2013-8-1 / CNY 79.00

本书介绍了如何使用Web标准技术来为iPhone和iPad制作Web应用。书中利用最前沿的Web和移动技术,演示了如何使用HTML5来完成繁重的基础工作,如何使用CSS3来制作外观,以及如何使用JavaScript来为移动网站或Web应用添加程序逻辑。 通过阅读本书,读者可以掌握面向移动的项目的开发流程。作者逐章递进,引导读者了解iOS设计与开发的各个步骤。读者可以学习到如下知识: 设......一起来看看 《iOS Web应用开发》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具