Java 方法需要满足特定的先决条件才能在 GraalVM 中从 C 或 C++ 成功运行。
在设计将使用@CEntryPoint 注释的Java 入口点方法时,应考虑这些先决条件。提到以下前提条件in the CEntryPoint documentation。
- Java 入口点方法只允许包含原始 Java 类型、字值和枚举。此外,为了实际使用
Enum,enum class 必须有 CEnum 注释。In the CEntryPoint documentation。
- Java 入口点方法应该是静态的。
- Java 入口点方法应该捕获所有异常,因为它不应该抛出任何异常。如果未捕获到异常,则打印该异常,然后终止该过程。然而,
@CEntryPoint 文档明确提到要捕获 java 入口点方法中的所有异常。
-
IsolateThread 参数是必需的。更准确地说
执行上下文必须作为参数传递,并且可以是
特定于当前线程的 IsolateThread,或 Isolate
对于附加了当前线程的隔离。这些指针
可以通过 CurrentIsolate 的方法获得。当有更多
不是这些类型的一个参数,必须是其中一个参数
为 IsolateThread 使用 CEntryPoint.IsolateThreadContext 进行注释,
或 CEntryPoint.IsolateContext 用于隔离。
您问题中的示例会引发此错误,因为 myFunc 方法签名包含对象,例如 String 参数。即x和y。根据上面的前提条件 1,这是不允许的。这就是错误描述试图表达的意思。
解决方案是使用提供的功能在 Java 类型和 C 类型之间进行转换。在这种情况下,为了在C 和Java 之间传递文本,我们可以使用CCharPointer。由于 C 和 Java 中的文本建模方式不同,因此必须将 Java String 转换为 C *char,反之亦然。
创建并返回 Java 字符串
下面有一个例子,可以在byte[]代表文本时使用。
//These are the imports needed
import org.graalvm.nativeimage.c.type.CCharPointer;
import org.graalvm.nativeimage.c.type.CTypeConversion;
@CEntryPoint(name = "myFunc")
public static CCharPointer myFunc(IsolateThread thread, CCharPointer x, CCharPointer y) {
//Convert C *char to Java String
final String xString= CTypeConversion.toJavaString(x);
final String yString= CTypeConversion.toJavaString(y);
//logic goes here
//Convert Java String to C *char
try(final CTypeConversion.CCharPointerHolder holder=CTypeConversion.toCString("Hello from Java")){
final CCharPointer result=holder.get();
return result;
}
}
使用并返回在 C 中分配的数组
您也可以遵循 C 风格,将 C 中的数组作为参数传递,然后使用该数组在 Java 中写入结果字节值。方法CCharPointer.write(int,byte) 可以将Java byte 值写入*char 或char[] 中的特定数组索引。如果需要,也可以返回字节数组。
@CEntryPoint(name = "myFunc2")
public static CCharPointer myFunc2(IsolateThread thread
, CCharPointer x, CCharPointer y
, CCharPointer resultArray, int resultArrayLength) {
//Convert C *char to Java String
final String xString= CTypeConversion.toJavaString(x);
final String yString= CTypeConversion.toJavaString(y);
//logic goes here
//Fill in the result array
final byte sampleByteValue=7;
for(int index =0; index<resultArrayLength; index++){
resultArray.write(index, sampleByteValue);
}
return resultArray;
}
使用Java NIO ByteBuffer
对于较大的字节数组,您可以检查CTypeConversion,它可以创建一个具有特定容量的Java NIO ByteBuffer,该容量指的是本机内存。请注意
调用者负责确保内存可以安全
在使用 ByteBuffer 时访问,并释放内存
之后。