我已成功从C函数接收一个void *到Java中并根据上下文将其转换为适当的类型,但现在我必须以相反的方式完成整个事情,而我无法让它发挥作用。
具体来说,我试图调用的函数需要一个void *,在这种情况下,隐藏一个char *,后面当然隐藏了一个char []。 C函数不会操纵数据,它只是读取它。
所以我尝试从字符串创建一个Byte [],然后将指针传递给它的第一个元素,如下所示:
//transform the string into a byte array
byte[] byte_value = new_value.getBytes();
//create a pointer to the first byte
ByteByReference valueptr = new ByteByReference(byte_value[0]);
//pass the pointer to the function that sets the value
int result = lib.gp_widget_set_value(widget, valueptr.getPointer());
令我惊讶的是,没有任何事情发生。令我沮丧的是,该功能似乎根本无法获取数据。谁能看到我做错了什么?
函数gp_widget_set_value由JNAerator基于libgphoto2生成。生成的函数头包括生成的注释如下所示:
/**
* Original signature : <code>int gp_widget_set_value(CameraWidget*, const void*)</code><br>
* <i>native declaration : /usr/include/gphoto2/gphoto2-widget.h:840</i>
*/
int gp_widget_set_value(Gphoto2Library.CameraWidget widget, Pointer value);
Gphoto API文档中实际C函数的文档:
int gp_widget_set_value(CameraWidget * widget,const void * 价值)
设置小部件的值。
参数 widget一个CameraWidget 价值
返回 gphoto2错误代码。
请传递(char *)GP_WIDGET_MENU,GP_WIDGET_TEXT, GP_WIDGET_RADIO,(float)表示GP_WIDGET_RANGE,(int)表示 GP_WIDGET_DATE,GP_WIDGET_TOGGLE和(CameraWidgetCallback) GP_WIDGET_BUTTON。
如果您想知道,最后一行是指小部件类型,是的,我确定这是正确的。
答案 0 :(得分:1)
您可以使用以下命令以正确的编码获取字节:
byte[] bytes = new_value.getBytes( StandardCharsets.UTF_8 ); //or .US_ASCII
但您最需要做的是使用JNA's byte[] Native.toByteArray(String s)
如果出于某种原因无效,那么应该这样做:
Pointer m = new Memory( new_value.length() + 1 ); //assumes ASCII
m.setString( 0, new_value );
int result = lib.gp_widget_set_value( widget, m );
答案 1 :(得分:1)
你不需要任何复杂的事情。 JNA负责处理最常见的C语言。 JNAerator在字面上给出了函数声明中的内容;它无法弄清楚C字符串,char缓冲区,char数组或指向单个char的指针之间的语义差异。
int gp_widget_set_value(Gphoto2Library.CameraWidget widget, String value);
请注意,在这种情况下传递给本机函数的内存是临时的,并且在函数返回时将被处理掉。如果你需要记忆(不是一个好主意),你需要使用Memory
并保持对它的引用。