如何从C+;调用非原语类型作为参数的Java入口点方法+;使用GraalVM
我正在尝试使用graalvm创建java代码的共享库(带有头文件和库文件的dll)如何从C+;调用非原语类型作为参数的Java入口点方法+;使用GraalVM,java,c++,visual-c++,graalvm,graalvm-native-image,Java,C++,Visual C++,Graalvm,Graalvm Native Image,我正在尝试使用graalvm创建java代码的共享库(带有头文件和库文件的dll) 有一个java方法,它有2个字符串类型的参数,我将从C++调用。 我正在使用一个maven项目,我无法用java代码创建dll,我正在使用graalvm将java代码转换为dll 我的java代码如下所示: package demo; import org.graalvm.nativeimage.IsolateThread; import org.graalvm.nativeimage.c.function.C
有一个java方法,它有2个字符串类型的参数,我将从C++调用。 我正在使用一个maven项目,我无法用java代码创建dll,我正在使用graalvm将java代码转换为dll
我的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;
}
但是当我试图将代码构建到dll中时,我遇到了这个错误
错误:入口点方法参数类型仅限于基元类型、单词类型和枚举(@CEnum):demo.MyClass.myFunc(IsolateThread、String、String)
我搜索了一下,但没有找到解决这个问题的合适方法。
这里有人能告诉我如何用C++调用java方法和非原始数据类型吗?
任何建议都是一个很大的帮助,感谢您提前提出了一个特定的前提条件,java的方法需要在GraalVM中成功地从C或C++中运行。 在设计要用
@CEntryPoint
注释的Java入口点方法时,也应该考虑到这些因素。提到了以下先决条件
Enum
,Enum类必须有CEnum
注释
@CEntryPoint
文档明确提到捕获java入口点方法内部的所有异常IsolateThread
参数。更准确地说myFunc
方法签名包含对象,例如String
参数。即x
和y
。根据上述前提条件1,这是不允许的。这就是错误描述试图说的
解决方案是使用提供的功能在Java类型和C类型之间进行转换。在这种情况下,为了在C
和Java
之间传递文本,我们可以使用。由于文本在C
和Java
中的建模方式不同,因此Java字符串必须转换为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中写入结果字节值。该方法可以将Java字节
值写入*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;
}
@CEntryPoint(name=“myFunc2”)
公共静态CCharPointer myFunc2(IsolateThread线程
,CCharPointer x,CCharPointer y
,CCharPointer结果数组,int结果数组长度){
//将C*字符转换为Java字符串
最终字符串xString=CTypeConversion.toJavaString(x);
最终字符串yString=CTypeConversion.toJavaString(y);
//逻辑就在这里
//填写结果数组
最终字节sampleByteValue=7;
对于(int index=0;index x1),非常感谢,我了解java和C++之间字符串类型的转换。将不包含文本它将只包含字节,它是否也适用于此?不客气。是的,我将更新我的答案,以包括一个示例。我的字节数组将是巨大的,我可以一次性写入整个字节数组,还是只需在特定索引处写入它?使用NIO字节缓冲区本身就是一个主题,可能是另一个问题因为NIO是独立于GraalVM的东西。你可以在一个新问题中尝试一些东西,如果可能的话,我可以提供帮助。例如,在这里传递对象是不可能的,正如我的答案和javadoc中的前提条件1所述,你能得到的最接近的是使用一种独立的格式,例如JSON和封送/解封送。您好r答案有效,我的编码类型有问题。实际上,我需要一个base64编码的字符串,但我不知道CTypeConversion使用什么编码,因为我无法使用base64解码器将其解码为字节数组,你能帮我吗?