版本
- 適用於 JDK 23 的 GraalVM (最新版)
- 適用於 JDK 24 的 GraalVM (搶先體驗版)
- 適用於 JDK 21 的 GraalVM
- 適用於 JDK 17 的 GraalVM
- 封存
- 開發版本
互通性
GraalVM 支援多種其他程式語言,包括 JavaScript、Python、Ruby 和 R。雖然 GraalVM 的 lli
實作旨在執行 LLVM 位元碼,但也提供了程式語言互通性的 API,讓您可以執行任何其他 GraalVM 支援的語言的程式碼。
像 JavaScript 這樣的動態語言通常會依名稱存取物件成員。由於名稱通常不會保留在 LLVM 位元碼中,因此必須啟用偵錯資訊來進行編譯 (GraalVM 隨附的 LLVM 工具鏈會自動啟用偵錯資訊)。
以下範例示範如何使用 API 與其他程式語言進行互通。
在名為 cpart.c 的檔案中定義 C 結構來表示點,並實作配置函式
// cpart.c
#include <graalvm/llvm/polyglot.h>
#include <stdlib.h>
#include <stdio.h>
struct Point {
double x;
double y;
};
POLYGLOT_DECLARE_STRUCT(Point)
void *allocNativePoint() {
struct Point *ret = malloc(sizeof(*ret));
return polyglot_from_Point(ret);
}
void *allocNativePointArray(int length) {
struct Point *ret = calloc(length, sizeof(*ret));
return polyglot_from_Point_array(ret, length);
}
void freeNativePoint(struct Point *p) {
free(p);
}
void printPoint(struct Point *p) {
printf("Point<%f,%f>\n", p->x, p->y);
}
請確定 LLVM_TOOLCHAIN
解析為 GraalVM LLVM 工具鏈 (lli --print-toolchain-path
),然後編譯 cpart.c (graalvm-llvm 程式庫定義了範例中使用的 Polyglot API 函式)
$LLVM_TOOLCHAIN/clang -shared cpart.c -lgraalvm-llvm -o cpart.so
然後,您可以從其他語言存取此 C/C++ 程式碼。例如,將此 JavaScript 程式碼儲存到 jspart.js 檔案中
// Load and parse the LLVM bitcode into GraalVM
var cpart = Polyglot.evalFile("llvm" ,"cpart.so");
// Allocate a light-weight C struct
var point = cpart.allocNativePoint();
// Access it as if it was a JS object
point.x = 5;
point.y = 7;
// Pass it back to a native function
cpart.printPoint(point);
// Allocate an array of structs
var pointArray = cpart.allocNativePointArray(15);
// Access this array like it was a JS array
for (var i = 0; i < pointArray.length; i++) {
var p = pointArray[i];
p.x = i;
p.y = 2*i;
}
cpart.printPoint(pointArray[3]);
// Additionally, pass a JS object to a native function
cpart.printPoint({x: 17, y: 42});
// Free the unmanaged data objects
cpart.freeNativePoint(point);
cpart.freeNativePoint(pointArray);
最後,執行此 JavaScript 檔案
js --polyglot jspart.js
Point<5.000000,7.000000>
Point<3.000000,6.000000>
Point<17.000000,42.000000>
Polyglot C API #
還有更低層級的 API 函式,可直接從 C 存取 polyglot 值。如需更多詳細資訊,請參閱Polyglot 程式設計參考文件以及 polyglot.h
中的註解。
例如,此程式會從 C 配置和存取 Java 陣列
#include <stdio.h>
#include <graalvm/llvm/polyglot.h>
int main() {
void *arrayType = polyglot_java_type("int[]");
void *array = polyglot_new_instance(arrayType, 4);
polyglot_set_array_element(array, 2, 24);
int element = polyglot_as_i32(polyglot_get_array_element(array, 2));
printf("%d\n", element);
return element;
}
將其編譯為 LLVM 位元碼
$LLVM_TOOLCHAIN/clang polyglot.c -lgraalvm-llvm -o polyglot
然後執行它
lli polyglot
24
嵌入到 Java 中 #
您可以將 LLVM 位元碼嵌入到 Java 主應用程式中。
例如,撰寫一個 Java 類別 Polyglot.java
,其中會嵌入 LLVM 位元碼來執行先前的範例
import java.io.*;
import org.graalvm.polyglot.*;
class Polyglot {
public static void main(String[] args) throws IOException {
Context polyglot = Context.newBuilder().
allowAllAccess(true).build();
File file = new File("polyglot");
Source source = Source.newBuilder("llvm", file).build();
Value cpart = polyglot.eval(source);
cpart.execute();
}
}
編譯並執行它
javac Polyglot.java
java Polyglot
24
如需更多資訊,請參閱嵌入語言參考文件。