为了在 GraalVM 中从 C 或 C++ 成功运行,Java 方法需要满足特定的先决条件。在设计将要使用 注释的 Java 入口点方法时应考虑这些前提条件@CEntryPoint
。CEntryPoint 文档中提到了以下先决条件。
- Java 入口点方法只允许包含原始 Java 类型、字值和枚举。另外为了实际使用
Enum
必须enum class
有一个CEnum
注解。在 CEntryPoint 文档中。
- Java 入口点方法应该是静态的。
- Java 入口点方法应该捕获所有异常,因为它不应该抛出任何异常。如果未捕获到异常,则打印该异常,然后终止该过程。但是,
@CEntryPoint
文档明确提到要捕获 java 入口点方法中的所有异常。
- 需要一个
IsolateThread
参数。更确切地说
执行上下文必须作为参数传递,可以是特定于当前线程的 IsolateThread,也可以是附加当前线程的隔离的 Isolate。这些指针可以通过 CurrentIsolate 的方法获得。当这些类型的参数不止一个时,对于 IsolateThread,必须使用 CEntryPoint.IsolateThreadContext 或对 Isolate 使用 CEntryPoint.IsolateContext 注释其中一个参数。
您问题中的示例会引发此错误,因为myFunc
方法签名包含对象,例如String
参数。即x
和y
。根据上面的前提条件1 ,这是不允许的。这就是错误描述试图说的。
解决方案是使用提供的功能在 Java 类型和 C 类型之间进行转换。在这种情况下,为了在和之间传递文本C
,Java
我们可以使用CCharPointer
. 由于文本在C
和中Java
的建模方式不同,Java String
因此必须将 a 转换为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)可以将值写入orJava 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 时可以安全地访问内存,并在之后释放内存。