[英]How to call a Java entrypoint method with non-primitive types as parameters from C++ using GraalVM
I am trying to create a shared library(dll with header and lib files) of a java code using graalvm.我正在尝试使用 graalvm 创建 Java 代码的共享库(带有头文件和 lib 文件的 dll)。
there will be one java method with 2 parameters of type String which I will call from c++.将有一个带有 2 个 String 类型参数的 java 方法,我将从 C++ 调用它。
I am using a maven project, I am not able to create the dll out of my java code, I am using graalvm to convert my java code to dll.我正在使用一个 Maven 项目,我无法从我的 java 代码中创建 dll,我正在使用 graalvm 将我的 java 代码转换为 dll。
My java code looks like this:我的 Java 代码如下所示:
package demo;
import org.graalvm.nativeimage.IsolateThread;
import org.graalvm.nativeimage.c.function.CEntryPoint;
public class MyClass{
@CEntryPoint (name = "myFunc")
public static byte[] myfunc(IsolateThread thread, String x, String y) {
// logic goes here
byte[] arr = "byte array will contain actual bytes".getBytes();
return arr;
}
but when I try to build the code into dll, I got this error但是当我尝试将代码构建到 dll 中时,我收到了这个错误
Error: Entry point method parameter types are restricted to primitive types, word types and enumerations (@CEnum): demo.MyClass.myFunc(IsolateThread, String, String)
错误:入口点方法参数类型仅限于原始类型、单词类型和枚举(@CEnum):demo.MyClass.myFunc(IsolateThread, String, String)
I searched but didn't find suitable solutions to this problem.我进行了搜索,但没有找到解决此问题的合适方法。 can anyone here please tell me how to call java methods from c++ with non-primitive datatypes any suggestions of any kind will be a great help, thanks in advance
这里的任何人都可以告诉我如何使用非原始数据类型从 C++ 调用 java 方法任何类型的任何建议都会有很大帮助,在此先感谢
There are specific preconditions that the a java method needs to fulfill in order to be successfully run from C or C++ in GraalVM.为了在 GraalVM 中从 C 或 C++ 成功运行 java 方法需要满足特定的先决条件。 These should also be taken into account when designing the Java entry point methods that are going to be annotated with
@CEntryPoint
.在设计将使用
@CEntryPoint
注释的 Java 入口点方法时,也应该考虑这些。 The following preconditions are mentioned in the CEntryPoint documentation . CEntryPoint 文档中提到了以下先决条件。
Enum
the enum class
must have a CEnum
annotation.Enum
, enum class
必须有一个CEnum
注释。 In the CEntryPoint documentation . @CEntryPoint
documentation explicitly mention to catch all exceptions inside the java entry point methods.@CEntryPoint
文档明确提到要捕获 java 入口点方法中的所有异常。IsolateThread
parameter is required.IsolateThread
参数。 More preciselyAn execution context must be passed as a parameter and can be either an IsolateThread that is specific to the current thread, or an Isolate for an isolate in which the current thread is attached.
执行上下文必须作为参数传递,并且可以是特定于当前线程的 IsolateThread,也可以是连接当前线程的隔离的 Isolate。 These pointers can be obtained via the methods of CurrentIsolate.
这些指针可以通过 CurrentIsolate 的方法获得。 When there is more than one parameter of these types, exactly one of the parameters must be annotated with CEntryPoint.IsolateThreadContext for IsolateThread, or CEntryPoint.IsolateContext for Isolate.
当这些类型的参数不止一个时,必须用 CEntryPoint.IsolateThreadContext 为 IsolateThread 或 CEntryPoint.IsolateContext 为 Isolate 对其中一个参数进行注释。
The sample in your question throws this error since the myFunc
method signature includes objects, for instance the String
parameters.您问题中的示例会引发此错误,因为
myFunc
方法签名包含对象,例如String
参数。 Namely x
and y
.即
x
和y
。 This is not allowed according to the precondition 1 from above.根据上述前提条件1 ,这是不允许的。 This is what the error description tries to say.
这就是错误描述试图说明的内容。
The solution is to use the functionality provided to convert between Java types and C types.解决方案是使用提供的功能在 Java 类型和 C 类型之间进行转换。 In this case in order to pass text between
C
and Java
we can use a CCharPointer
.在这种情况下,为了在
C
和Java
之间传递文本,我们可以使用CCharPointer
。 Since text is modeled differently in C
and Java
, a Java String
must be converted to C *char
and vice versa.由于文本在
C
和Java
建模不同,因此必须将Java String
转换为C *char
,反之亦然。
Creating and returning a Java String创建并返回 Java 字符串
There is an example below that can be used when byte[]
represents text.当
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;
}
}
Using and returning an array allocated in C使用和返回在 C 中分配的数组
You can also follow a C style and pass as an argument an array in C and then use this array to write the result byte values in Java.您也可以遵循 C 风格并将 C 中的数组作为参数传递,然后使用该数组在 Java 中写入结果字节值。 The method CCharPointer.write(int,byte) can write
Java byte
values to specific array indexes in the *char
or char[]
.方法CCharPointer.write(int,byte)可以将
Java byte
值写入*char
或char[]
中的特定数组索引。 The byte array can also be returned, if needed.如果需要,也可以返回字节数组。
@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;
}
Using a Java NIO ByteBuffer使用Java NIO ByteBuffer
For larger byte arrays you can check CTypeConversion that can create a Java NIO ByteBuffer
with a specific capacity that refers to the native memory.对于更大的字节数组,您可以检查CTypeConversion ,它可以创建一个具有特定容量的
Java NIO ByteBuffer
,该容量是指本机内存。 Note that注意
the caller is responsible for ensuring that the memory can be safely accessed while the ByteBuffer is used, and for freeing the memory afterwards.
调用者负责确保在使用 ByteBuffer 时可以安全地访问内存,并在之后释放内存。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.