简体   繁体   English

JNA:如何将字符串作为void *从Java传递到C

[英]JNA: How to pass a string as void* from Java to C

I have successfully received a void* from a C function into Java and cast it into the apropriate type depending on context, but now I have to do the whole thing the other way around, and I can't get it to work. 我已经成功地从C函数接收到void *并将其转换为Java,并根据上下文将其转换为适当的类型,但是现在我必须反过来做整个事情,而我无法使其正常工作。

Specifically, the function I am trying to call demands a void*, behind which, in this case, hides a char*, behind which of course hides a char[]. 具体来说,我要调用的函数需要一个void *,在这种情况下,在此之后将隐藏一个char *,当然在其后还将隐藏一个char []。 The C-function doesn't manipulate the data, it just reads it. C函数不操作数据,它只是读取数据。

So I've tried creating a Byte[] from a string and then passing a pointer to the first element of it, like so: 因此,我尝试从字符串创建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()); 

To my surprise, nothing crashes. 令我惊讶的是,没有崩溃。 To my dismay, the function doesn't seem to get the data at all. 令我沮丧的是,该函数似乎根本无法获取数据。 Can anybody see what I'm doing wrong? 有人可以看到我在做什么吗?

The function gp_widget_set_value was generated by JNAerator based on libgphoto2. 函数gp_widget_set_value由JNAerator基于libgphoto2生成。 The generated function header including generated comment looks like this: 包含生成的注释的生成的函数标头如下所示:

/**
 * 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);

The documentation of the actual C function from the Gphoto API docs: Gphoto API文档中实际C函数的文档:

int gp_widget_set_value ( CameraWidget * widget, const void * value ) int gp_widget_set_value(CameraWidget *小部件,const void * value)

Sets the value of the widget. 设置小部件的值。

Parameters widget a CameraWidget value 参数小部件的CameraWidget值

Returns a gphoto2 error code. 返回gphoto2错误代码。

Please pass (char*) for GP_WIDGET_MENU, GP_WIDGET_TEXT, GP_WIDGET_RADIO, (float) for GP_WIDGET_RANGE, (int) for GP_WIDGET_DATE, GP_WIDGET_TOGGLE, and (CameraWidgetCallback) for GP_WIDGET_BUTTON. 请传递(char *)表示GP_WIDGET_MENU,GP_WIDGET_TEXT,GP_WIDGET_RADIO,(浮点数)表示GP_WIDGET_RANGE,(int)表示GP_WIDGET_DATE,GP_WIDGET_TOGGLE和(CameraWidgetCallback)表示GP_WIDGET_BUTTON。

In case you are wondering, the last line refers to the widget type, and yes, I'm making very sure that that is correct. 如果您想知道,最后一行是指小部件类型,是的,我确定这是正确的。

You could use the following to get the bytes in the proper encoding: 您可以使用以下命令以正确的编码获取字节:

byte[] bytes = new_value.getBytes( StandardCharsets.UTF_8 ); //or .US_ASCII

But what you most probably need to do is to use JNA's byte[] Native.toByteArray(String s) 但是,您最可能需要做的是使用JNA的byte [] Native.toByteArray(String s)

If for some reason that does not work, then this should do it: 如果由于某种原因不起作用,则应这样做:

Pointer m = new Memory( new_value.length() + 1 ); //assumes ASCII
m.setString( 0, new_value );
int result = lib.gp_widget_set_value( widget, m );

You don't need anything complicated. 您不需要任何复杂的事情。 JNA takes care of most common C idioms. JNA负责最常见的C习惯用法。 JNAerator is giving you literally what's in the function declarations; JNAerator实际上为您提供了函数声明中的内容; it can't figure out the semantic difference between a C string, a char buffer, an array of char, or a pointer to a single char. 它无法弄清C字符串,char缓冲区,char数组或指向单个char的指针之间的语义差异。

int gp_widget_set_value(Gphoto2Library.CameraWidget widget, String value);

Note that the memory passed to the native function in this case is temporary and will be disposed of when the function returns. 请注意,在这种情况下,传递给本机函数的内存是临时的,并且在函数返回时将被丢弃。 If you need the memory to stick around (not a good idea), you'd need to use Memory and maintain a reference to it. 如果您需要保留Memory (不是一个好主意),则需要使用Memory并维护对其的引用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM